关于elasticsearch:ElasticSearh复习笔记

51次阅读

共计 7467 个字符,预计需要花费 19 分钟才能阅读完成。

ES 根底

概念

1.1 ElasticSearh 是什么

Elasticsearch 是一个分布式可扩大的 实时搜寻和剖析引擎 , 一个建设在全文搜索引擎 Apache Lucene(TM) 根底上的搜索引擎,被广泛应用于 全文搜寻

它能够疾速、实时地存储、搜寻和剖析大量数据。

1.2 利用场景

  • 作为海量数据的存储工具(亿级),分布式实时文件存储,并将每一个字段都编入索引,使其能够被搜寻。
  • 简单的数据分析(ELK 技术,elasticsearch+logstash+kibana)
  • 分布式搜索引擎。能够扩大到上百台服务器,解决 PB 级别的结构化或非结构化数据。

1.3 集群构造

假如集群中有 3 台 es,1 台主节点,2 台从节点,创立索引的时候,定义了为这个索引创立 3 个分片 shard,1 个正本 replica

  1. 这个索引一共有 6 个分片,3 个 shard 分片集,每个 shard 有 1 个 replica 正本集,所以一共就有 6 个分片集
  2. shard 和对应的 replica 是不会在同一台机器上的
  3. 主节点负责节点和索引的增删改查,并不解决文档级别的增删改查

1.4 集群原理

倒排索引

正排索引:通过 ID 映射到相应的记录。

倒排索引:就是 关键词到文档 ID 的映射,每个关键词都对应着一系列的文件,这些文件中都呈现了关键词。

DocId Doc
1 谷歌地图之父跳槽 Facebook
2 谷歌地图之父加盟 Facebook
3 谷歌地图创始人拉斯来到谷歌加盟 Facebook
4 谷歌地图之父跳槽 Facebook 与 Wave 我的项目勾销无关
5 谷歌地图之父拉斯加盟社交网站 Facebook

倒排索引:用户输出查问 Facebook,搜寻零碎查找倒排索引,从中读出蕴含这个单词的文档,这些文档就是提供给用户的搜寻后果。

  • 倒排索引中的所有词项对应一个或多个文档;
  • 倒排索引中的词项 依据字典程序升序排列
WordId Word DocIds
1 谷歌 1, 2, 3, 4, 5
2 地图 1, 2, 3, 4, 5
3 之父 1, 2, 4, 5
4 跳槽 1, 4
5 Facebook 1, 2, 3, 4, 5
6 加盟 2, 3, 5
7 创始人 3
8 拉斯 3, 5
9 来到 3
10 4
写入数据
  • 客户端抉择一个 node 发送申请过来,这个 node 就是 coordinating node(协调节点)。
  • coordinating node 对 document 进行 路由,将申请转发给对应的 node(有 primary shard)。
  • 理论的 node 上的 primary shard 解决申请,而后将数据同步到 replica node
  • coordinating node 如果发现 primary node 和所有 replica node 都搞定之后,就返回响应后果给客户端。

底层原理:

  • 数据先写入内存 buffer,而后每隔 1s,将数据 refresh 到 os cache(操作系统缓存),到了 os cache 数据就能被搜寻到(所以咱们才说 es 从写入到能被搜寻到,两头有 1s 的提早)。
  • 每隔 5s,将数据写入 translog 文件(这样如果机器宕机,内存数据全没,最多会有 5s 的数据失落),translog 大到肯定水平,或者默认每隔 30mins,会触发 commit 操作,将缓冲区的数据都 flush 到 segment file 磁盘文件中。

总结:

  • es 是准实时的,buffer 中的数据被 refresh 操作刷入 os cache 中,这个数据才能够被搜寻到
  • ES 是可能会失落数据的:translog 先写入 os cache,默认每 5 秒刷一次到磁盘,如果此时机器挂了,会 失落 5 秒钟的数据。
读数据

写申请是写入 primary shard,而后同步给所有的 replica shard;读申请能够从 primary shard 或 replica shard 读取,采纳的是随机轮询算法。

能够通过 doc id 来查问,会依据 doc id 进行 hash,从而判断出 doc id 要调配到哪个 shard 下面去,即从那个 shard 去查问。

  • 客户端发送申请到 任意 一个 node,成为 coordinate node
  • coordinate nodedoc id 进行哈希路由,将申请转发到对应的 node,此时会应用 round-robin 随机轮询算法,在 primary shard 以及其所有 replica 中随机抉择一个,让读申请负载平衡。
  • 接管申请的 node 返回 document 给 coordinate node
  • coordinate node 返回 document 给客户端。
分片路由形式

分片的路由形式相似于 redis 的 hash 槽。

当要插入文档或者查问文档时,这个文档将存到哪个分片,查问的时候到哪个分片中去查问这个文档,是依据 hash 取模实现的。

ES 高可用
  1. es 的分片 shard 和正本集 replica,不会位于同一个 es 节点(es-node)。
  2. shard 会主动把内容复制到 replica
  3. es shard 和 replica 的负载平衡路由是有 es 外部主动实现的,内部用户无感知。
ES 扩容

ES 扩容过程中,用户无需去关注分片具体是怎么迁徙到新 es-node 的,整个过程主动实现的。

1.5 设计剖析

  1. 商品数据变动时,将变动同步到 ES 中
  2. 查问商品列表或搜寻商品时,从 ES 中查问数据
  3. 为了进步 ES 吞吐率和伸缩性以及高可用,须要搭建 ES 集群架构
  4. 为了方便管理和监控,须要可视化工具 es-head 和 kibana

应用思路:

  1. 商品数据变动时,将变动同步到 es 中
  2. 查问商品列表数据或搜寻商品时,从 es 中查问数据
  3. 为了进步 es 吞吐率和伸缩性以及高可用,咱们须要搭建一个 es 集群架构
  4. 为了方便管理和监控,咱们须要可视化工具 es-head 和 kibana

存储概念

ES 是面向文档 (document oriented) 的,它能够存储整个对象或文档(document)。

ES 会索引 (index) 每个文档的内容使之能够被搜寻。

ES 能够对文档(而非成行成列的数据)进行索引、搜寻、排序、过滤。

文档属性
  • index:索引库,相似于关系型数据库里的“数据库”—它是咱们存储和索引关联数据的中央。
  • _type:类型,相似于关系型数据库中表。能够是大写或小写,不能蕴含下划线或逗号。咱们将应用 employee 做为类型名。(ES7 当前停用,固定为_doc)
  • _id:与 _index 和 _type 组合时,就能够在 ELasticsearch 中惟一标识(相似于主键)一个文档。当创立一个文档,你能够自定义 _id,也能够让 Elasticsearch 帮你主动生成。
  • _uid:文档惟一标识(type#id)
  • _source:文档原始数据
  • _all:所有字段的连贯字符串

ES 集群能够蕴含多个索引(indices)(数据库),每个索引蕴含多个文档(documents)(行),而后每个文档蕴含多个字段(Fields)(列)。

Mapping:定义索引下的字段解决规定,即索引如何建设、索引类型、是否保留原始索引 JSON 文档、是否压缩原始 JSON 文档、是否须要分词解决、如何进行分词解决等。

关系数据库(MYSQL) 数据库 DB 表 TABLE 行 ROW 列 Column Schema
Elasticsearch 索引库 Indices(数据库) 类型 Types(表) 文档 Documents(行) 字段 Fields(列) Mapping

2. 索引创立

创立索引 PUT

申请地址:http://ip: 端口 / 索引名称

留神:索引名称必须小写

示例:http://localhost:9200/goods_list

{
    "settings":{
        "number_of_shards":3,    // 分片数量
        "number_of_replicas":1     // 正本数量
    },
    "mappings":{
            "properties":{"id":{"type":"integer"},
                "goods_name":{"type":"text"},
                "goods_description":{"type":"text"},
                "goods_info":{"type":"text"}
            }
        }
}
增加数据

申请地址:http://ip: 端口 / 索引名 /_doc/ 商品 id

留神:

  1. 增加数据时指定的某个字段不存在时,es 会主动创立该字段
  2. 指定 id,不存在则创立,存在则更新
指定 ID 创立数据:
PUT /goods_list/_doc/123
{
  "id": "123",
  "goods_name": "测试商品的名称",
  "goods_description": "测试商品的形容",
  "goods_info": "。。。"
}
ES 内置 ID 创立(主动生成_id)
POST  /goods_list/_doc/
{
  "id": "123456",
  "goods_name": "ES 内置 ID 创立数据",
  "goods_description": "应用 ES 外部进行文档数据 ID 的生成",
  "goods_info": "。。。"
}

3. 查问数据

  1. 获取索引中所有文档:
GET /goods_list/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {"goods_name": "测试商品的名称"}
        }
      ]
    }
  }
}
  1. 指定 ID 查问
GET http://192.168.30.128:9201/goods_list/_doc/123
  1. 带条件查问
GET /goods_list/_search/
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {"goods_name": "ES 内置 ID 创立数据"} 
        },
        {
        "match" : {"goods_description": "ES 外部"}
        }
      ]
    }
  }
}
  1. 查问局部字段
GET /{index}/{type}/{id}?_source=fullName,email
  1. 只返回文档内容,不要元数据
GET /{index}/{type}/{id}/_source
  1. 批量获取 1
GET http://192.168.30.128:9201/_mget
{
    "docs": [
        {
            "_index": "goods_list", 
            "_type": "_doc", 
            "_id": 123
        }, 
        {
            "_index": "goods_list", 
            "_type": "_doc", 
            "_id": 1, 
            "_source": "email,age"
        }
    ]
}
  1. 批量获取 2
GET  http://192.168.30.128:9201/goods_list/_doc/_mget
{
    "ids": [
        "123", 
        "1"
    ]
}
  1. 分页搜寻
GET crm/_doc/_search?size=5 #查问 5 条
GET goods_list/_doc/_search?size=5&from=5 #查问 6 -10
GET goods_list/_doc/_search?size=5&from=10 #查问 11-15 
  1. 查问字符串
http://192.168.30.128:9201/goods_list/_doc/_search?q=goods_name: 商品

4. 查问条件精讲

精准查问 term

查问条件都在路由的 _serach 上面进行,但能够多个条件进行组织和安顿。

term 是代表齐全匹配,即不进行分词器剖析,文档中必须蕴含整个搜寻的词汇。

trem 单值

字段只有一个值时候,用 term 关键词查问。

精准查问,不须要查问进行评分计算。constant_score 示意非评分模式。

GET http://192.168.30.128:9200/good_list/_doc/_search 
{
    "query" : {  
        "constant_score" : {  
             "filter" : {  
                "term" : {"biz_id" : "1909190023901225"}  
            }  
        }  
    }  
}

terms 多值

字段有一多个值时候,用 terms 关键词查问,后跟数组

{
    "query":{
        "terms":{"biz_id":["1909190023901225"]
        }
    }
}

constant_score 非评分模式查问:

{  
    "query" : {  
        "constant_score" : {  
             "filter" : {  
                "terms" : {"biz_id" : ["1909190023901225","e1909190111365113"]  
                }  
            }  
        }  
    }  
}

多个字段查问:

{
    "query": [{
        "term": {"biz_id": "1909190023901225"}
    }, {
        "term": {"name": "sixstar"}
    }]
}
匹配查问 match
  • match 查问的时候,ES 会依据你给定的字段提供适合的分析器,而 term 查问不会有分析器剖析的过程
  • match 查问相当于含糊匹配,只蕴含其中一部分关键词就行。
match

进行 full text search 或者 exact value(非 string 字段或 not_analyzed 的字段),进行匹配

示例:查问字段 merchant_id 为 2501 的值,并按工夫倒序

{
   "query": {
     "match": {"merchant_id": "2501"}
   },
   "sort": [
     {
       "trade_finished_time": {"order": "desc"}
     }
   ]
}
match_all

匹配所有的,当不给查问条件时,默认全查

{
    "query": {"match_all": {}
    }
}
multi_match

同时对查问的关键词,多个字段同时进行匹配,即多个字段是 AND 的关系

{
    "query":{
        "multi_match":{
            "query":"2501",
            "fields":["merchant_id","_id"]
        }
    }
}

在在 fields 中,按 brandName(品牌名)、sortName(分类名)、productName(商品名)productKeyword(商品关键字),搜寻“牛仔 弹力”关键词,brandName 源值、拼音值、关键字值都是 100 分,sortName 源值、拼音值 80 分,productName 源值 60 分,productKeyword 值 20 分,分值由高到低优先级搜寻

{
  "query": {
    "multi_match": {
      "query": "牛仔 弹力",
      "fields": [
        "brandName^100",
        "brandName.brandName_pinyin^100",
        "brandName.brandName_keyword^100",
        "sortName^80",
        "sortName.sortName_pinyin^80",
        "productName^60",
        "productKeyword^20"
      ],
      "type": <multi-match-type>,
      "operator": "AND"
    }
  }
}     
match_phrase

match_phrase查问剖析文本,并从剖析文本中创立短语查问。
相似 match 查问,match_phrase 查问首先将查问字符串解析成一个词项列表,而后对这些词项进行搜寻,但只保留那些蕴含 全副 搜索词项,且 地位与搜索词项雷同的文档

如下,查问 quick brown、quick brown fox、brown fox 能够查问到,quick fox 查问不到

{  
      "query": {  
          "match_phrase": {"title": "quick brown fox"}  
      }  
} 

查问 a,b,a 和 b 之间隔 3 个字符能够查问到,隔不是 3 个查问不到

{
    "query":{
        "match_phrase" :{
            "query":"a,b",
            "slop":3
        }
    }
}
bool 查问

bool 查问蕴含四种操作符,别离是must,should,must_not,query。它们均是一种数组,数组外面是对应的判断条件

  • must:必须匹配,与 and 等价。并且参加计算分值
  • filter:过滤子句,必须匹配,但不参加计算分值
  • must_not:必须不匹配,与 not 等价,常过滤子句用,但不参加计算分值
  • should:选择性匹配,至多满足一条,与 OR 等价。参加计算分值
{  
    "query" : {  
        "filtered" : {  
            "filter" : {  
                "bool" : {  
                    "should" : [{ "term" : {"merchant_id" : 100}},  
                        {"term" : {"pay_type" : "3"}}  
                    ],  
                    "must_not" : {"term" : {"trade_type" : "2"}  
                    }  
                }  
            }  
        }  
    }  
}
filter 查问

过滤器,会查问对后果进行缓存,不会计算相关度,防止计算分值,执行速度十分快。

如下,查问出 statusactive的状态

{
  "query": {
    "bool": {
      "filter": {
        "term": {"status": "active"}
      }
    }
  }
}

filter 也常和 range 范畴查问一起联合应用,range 范畴可供组合的选项

  • gt : 大于
  • lt : 小于
  • gte : 大于等于
  • lte : 小于等于

如下,查问 merchant_id 值为 2501 下的交易数据

{
  "query": {
    "bool": {
      "must": {
        "term": {"merchant_id": "2501"}
      }, 
      "filter": {
        "range": {
          "trade_finished_time": {
            "from": "2019-09-01T00:00:00", 
            "to": "2019-09-30T23:59:59"
          }
        }
      }
    }
  }
}

must 下匹配,filter 进行过滤,range 定义范畴

{    
    "query": {    
        "bool": {    
            "must": [    
                {   
                    "match": {"title": "Search"}  
                },  
                {   
                    "match": {"content": "Elasticsearch"}  
                }  
            ],    
            "filter": [  
                {   
                    "term": {"status": "1"}  
                },  
                {   
                    "range": {   
                        "publish_date": {"gte": "2015-01-01"}  
                    }  
                }  
            ]  
        }  
     }  
} 
常见查问场景

1、查问商户 ID 为 3582,订单号为 360102199003072618,按工夫范畴过滤,按下单工夫倒序,每次查问 100 条

{
    "query": {
        "bool": {
            "must": [{
                "term": {"merchant_id": "3582"}
            }, {
                "term": {"order_num": "360102199003072618"}
            }],
            "filter": [{
                "range": {
                    "order_time": {
                        "from": "2019-11-01T17:00:00+08:00",
                        "to": "2019-11-01T20:00:00+08:00"
                    }
                }
            }]
        }
    },
    "size": 100,
    "sort": [{"order_time": "desc"}]
}

5. 批改数据

POST /goods_list/_doc/123/_update

{
"doc": {"goods_name": "测试商品的名称 Winner"}
}

6. 删除数据

DELETE  /goods_list/_doc/123

正文完
 0