Elastic search restful应用指南
  xP7vvuQeeYuv 2023年11月02日 85 0


倒排索引

全文搜索引擎目前主流的索引技术就是倒排索引的方式。传统的保存数据的方式都是:记录→单词。而倒排索引的保存数据的方式是:单词→记录, 基于分词技术构建倒排索引,每个记录保存数据时,都不会直接存入数据库。系统先会对数据进行分词,然后以倒排索引结构保存。

Elastic search restful应用指南_List


可以看到 Lucene 为倒排索引(Term Dictionary)部分又增加一层 Term Index 结构,用于快速定位,而这 Term Index 是缓存在内存中的,但 MySQL 的 B+tree 不在内存中,所以整体来看 ES 速度更快,但同时也更消耗资源(内存、磁盘)

集群操作

  • 集群健康状态 - GET /_cat/health?v
    绿 – 一切正常(集群功能齐全)
    黄 – 所有数据可用,但有些副本尚未分配(集群功能完全)
    红 – 有些数据不可用(集群部分功能)
  • 查看节点的情况 - GET /_cat/nodes?v
  • 查询各个索引状态 - GET /_cat/indices?v

索引

  • 创建索引 - PUT /film
  • 查看某一个索引的分片情况 - GET /_cat/shards/film?v
  • 删除索引 - DELETE /film

文档操作

  • 创建文档 - PUT /film/_doc/1 幂等性
{ "id":100,
  "name":"operation red sea",
  "doubanScore":8.5,
  "actorList":[  
  {"id":1,"name":"zhang yi"},
  {"id":2,"name":"hai qing"},
  {"id":3,"name":"zhang han yu"}
  ]}
  • POST /film/_doc/ 非幂等性
{
  "id":300,
  "name":"incident red sea",
  "doubanScore":5.0,
  "actorList":[  {"id":4,"name":"zhang cuishan111"}]
}

根据主键保证幂等性

  • 查询某一个索引中的全部文档 - GET /film/_search
  • 根据id查询某一个文档 - GET /film/_doc/3
  • 根据文档id,删除某一个文档 - DELETE /film/_doc/3
  • 修改文档 - PUT /film/_doc/3 对已经存在的文档进行替换(幂等性)
{
  "id":300,
  "name":"incident red sea",
  "doubanScore":5.0,
  "actorList":[  {"id":4,"name":"zhang cuishan"}]
}
  • POST /film/_doc/3/_update 更新文档中的某一个字段内容
{  "doc":  { "yy": "字符串" } }

Elasticsearch实际上并没有在底层执行就地更新,而是先删除旧文档,再添加新文档

  • 批量创建文档
POST /film/_doc/_bulk

{"index":{"_id":66}}
{"id":300,"name":"incident red sea","doubanScore":5.0,"actorList":[{"id":4,"name":"zhang cuishan"}]}
{"index":{"_id":88}}
{"id":300,"name":"incident red sea","doubanScore":5.0,"actorList":[{"id":4,"name":"zhang cuishan"}]}
  • 批量更新与删除文档
POST /film/_doc/_bulk

{"update":{"_id":"66"}}
{"doc": { "name": "wudangshanshang" } }
{"delete":{"_id":"88"}}

查询

GET /索引名/_search?q= &pretty这种方式不太适合复杂查询场景*

  • 查询指定字段 - GET /film/_search
{  "_source": ["name", "doubanScore"]}
  • 按分词查询(必须使用分词 text 类型)
GET /film/_search
{
  "query": {
    "match": {
      "actorList.name": "zhang han yu"
    }
  }}
  • 按短语查询 相当于like
GET /film/_search
{
  "query": {
    "match_phrase": {
      "actorList.name": "zhang han yu"
    }
  }}
  • 不分词 通过精准匹配进行查询
GET /film/_search
{
  "query": {
    "term": {
       "actorList.name.keyword":"zhang han yu"
    }
  }}
  • 容错匹配
GET /film/_search
{
  "query": {
    "fuzzy": {
      "name": "radd"
    }
  }}
  • 匹配和过滤同时
GET /film/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "red"
          }
        }], 
      "filter": {
        "term": {
          "actorList.id": "3"
        }
      }
    }}}
  • 范围过滤 ,将豆瓣评分在6到9的文档查询出来
GET /film/_search
{
  "query": {
    "range": {
      "doubanScore": {
        "gte": 6,
        "lte": 9
      }}
  }}
  • 按照豆瓣评分降序排序
GET /film/_search
{ "query": {
    "match": {
      "name": "red"
    }}, 
  "sort": [ {
      "doubanScore": {
        "order": "asc"
      }
    } ]}
  • 分页查询
GET /film/_search
{"from": 0,  "size": 2}
  • 搜索结果高亮
GET /film/_search
{
  "query": {
    "match": {
      "name": "red"
    }
  },
  "highlight": {
    "fields":  {"name":{} },
    "pre_tags": "<a>",
    "post_tags": "</a>"
  }
}
  • 聚合 - 聚合提供了对数据进行分组、统计的能力,类似于 SQL 中 Group By 和 SQL 聚合函数。在 ElasticSearch 中,可以同时返回搜索结果及其聚合计算结果,这是非常强大和高效的。
GET /film/_search
{
  "aggs": {
    "groupByName": {
      "terms": {
        "field": "actorList.name.keyword",
        "size": 10,
        "order": {
          "avg_score": "desc"
        }
      },
      "aggs": {
        "avg_score": {
          "avg": {
            "field": "doubanScore"
          } }
      }}
  }}

.keyword 是某个字符串字段,专门储存不分词格式的副本,在某些场景中只允许只用不分词的格式,比如过滤 filter 比如聚合 aggs, 所以字段要加上.keyword 的后缀

中文分词

  • 中文分词器对比
  • Elastic search restful应用指南_倒排索引_02

  • GET _analyze
{"analyzer": "ik_smart", "text": "我是中国人" }

{
  "tokens" : [
    {
      "token" : "我",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "CN_CHAR",
      "position" : 0
    },
    {
      "token" : "是",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "CN_CHAR",
      "position" : 1
    },
    {
      "token" : "中国人",
      "start_offset" : 2,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 2
    }
  ]
}
  • 自定义分词词库
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典 -->
 <entry key="ext_dict">./myword.txt</entry>
 <!--用户可以在这里配置自己的扩展停止词字典-->
 <entry key="ext_stopwords"></entry>

Mapping

  • 自定义mapping - 实际上每个 Type 中的字段是什么数据类型,由 mapping 定义,如果我们在创建 Index的时候,没有设定 mapping,系统会自动根据一条数据的格式来推断出该数据对应的字段类型,具体推断类型如下:true/false → boolean 1020 → long 20.1 → float “2018-02-01” → date “hello world” → text +keyword默认只有 text 会进行分词,keyword 是不会分词的字符串。mapping 除了自动定义还可以手动定义,但是只能对新加的、没有数据的字段进行定义,一旦有了数据就无法再做修改了。
PUT film01
{
  "mappings": {
    "movie":{
      "properties": {
        "id":{
          "type": "long"
        },
        "name":{
          "type": "keyword"
        },
        "doubanScore":{
          "type": "double"
        },
        "actorList":{
          "properties": {
            "id":{
              "type":"long"
            },
            "name":{
              "type":"keyword"
            }
          } } }
    } }}

copy索引数据

  • ElasticSearch 虽然强大,但是却不能动态修改 mapping 到时候我们有时候需要修改结构的时候不得不重新创建索引;ElasticSearch 为我们提供了一个 reindex 的命令,就是会将一个索引的快照数据 copy到另一个索引,默认情况下存在相同的_id 会进行覆盖(一般不会发生,除非是将两个索引的数据 copy 到一个索引中)
POST _reindex

{ "source": {
 "index": "my_index_name"
 },
 "dest": {
 "index": "my_index_name_new"
 }}

索引别名

  • 应用场景 - 给多个索引分组,把多个索引归并到一组
  • 给索引的一个子集创建视图相当于给 Index 加了一些过滤条件,缩小查询范围
  • 创建索引 并指定别名
PUT flim01
{ "aliases": {
      "film_chn_3_aliase": {}
  },
  • 查看所有别名
GET /_cat/aliases
  • 索引增加、删除索引
POST /_aliases
{ "actions": [
        { "remove": { "index": "movie_chn_1", "alias": "movie_chn_query" }},
        { "remove": { "index": "movie_chn_2", "alias": "movie_chn_query" }},
        { "add":    { "index": "movie_chn_3", "alias": "movie_chn_query" }}
    ]
}

索引模板

  • 应用场景
  • 分割索引
  • 分割索引就是根据时间间隔把一个业务索引切分成多个索引。比如 把 order_info 变成 order_info_20200101,order_info_20200102 这样做的好处有两个:
  • 结构变化的灵活性
  • 因为 ES 不允许对数据结构进行修改。但是实际使用中索引的结构和配置难免变化,那么只要对下一个间隔的索引进行修改,原来的索引维持原状。这样就有了一定的灵活性。要想实现这个效果,我们只需要在需要变化的索引那天将模板重新建立即可。
  • 查询范围优化
  • 因为一般情况并不会查询全部时间周期的数据,那么通过切分索引,物理上减少了扫描数据的范围,也是对性能的优化。
  • 创建模板
PUT _template/template_film
{"index_patterns": ["film_test*"],                  
  "settings": {                                               
    "number_of_shards": 1
  },
  "aliases" : { 
    "{index}-query": {},
    "film_test-query":{}
  },
  "mappings": {                                          
    "_doc": {
      "properties": {
        "id": {
          "type": "keyword"
        },
        "movie_name": {
          "type": "text",
          "analyzer": "ik_smart"
        }}
    }}}
  • 查询所有模板
GET _cat/templates
  • 查询模板详情
GET _template/template_film*


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
xP7vvuQeeYuv