Elasticsearch 操作语法全解

很详细,大家可以花点时间看看

目录

0 概念扫盲

elasticsearch

elastic stack(ELK)

Lucene

正向索引和倒排索引

        正向索引

        倒排索引

1. es概念

        文档和字段:

        索引和映射:

        DSL:相当于mysql中的sql语句

2. es操作

 2.1 mapping映射属性

 type:字段的数据类型,常见的简单类型有

index: 是否创建索引(是否参与搜索),默认为true

analyzer: 使用哪种分词器

properties: 字段,可以在字段中嵌套字段

2.2 索引库的CRUD

2.3 文档操作

2.4 DSL条件查询分类

2.5.1 排序

2.5.2 分页

2.5.3 高亮:

全部查询条件示例总结​

2.6 数据的聚合

2.7 自动补全 (后续

2.8 数据同步(后续


0 概念扫盲

  • elasticsearch

  •         – 一个开源的分布式搜索引擎,可以用来实现搜索、日志统计、分析、系统监控等功能
  • elastic stackELK

  •         –是以elasticsearch为核心的技术栈,包括beats、Logstash(数据抓取)、kibana(数据可视化)、elasticsearch(存储、计算、搜索数据)
  • Lucene

  •         –是Apache的开源搜索引擎类库,提供了搜索引擎的核心API
  • 正向索引和倒排索引

  •         正向索引

  •                   – 即根据id查文档再在文档中扫描关键字记录位置信息(全表扫描
  •         倒排索引

  •                 – 根据关键字找文档,创建一个词条表记录每个词条所在文档的id记录下来
  •                 – 搜索流程
  • :

 

1. es概念

  •         文档和字段:

  •                 文档(Document)相当于数据库表中的一条记录,字段(Field)相当于列
  •         索引和映射:

  •                 索引(index)是所有文档的集合相当于数据库中的表,数据库中的表有表结构,字段名,类型等约束信息,那么映射(mapping)就是索引中文档的约束信息。
  •         DSL:相当于mysql中的sql语句

2. es操作

 2.1 mapping映射属性

  •  type:字段的数据类型,常见的简单类型有

  1. 字符串:text(可分词的文本)、keyword(精确值,如ip地址
  2. 数值:long, integer, short , byte, double , float
  3. 布尔:boolean
  4. 日期:date
  5. 对象:object
  • index: 是否创建索引(是否参与搜索),默认为true

  • analyzer: 使用哪种分词器

  • properties: 字段,可以在字段中嵌套字段

2.2 索引库的CRUD

  • 创建索引库映射关系: PUT  /{索引库名}     请求参数:js
  • 查询索引库: GET  /{索引库名}
  • 修改索引库:
    •  倒排索引一旦数据结构发生改变需要重新创建倒排索引,因此索引库一旦创建无法修改mapping  但可以在mapping中添加新字段
    •  基本语法:
      • 请求方式:PUT
      •  请求路径:/索引库名/_mapping
      • 请求参数:js
  • 删除索引库:DELETE  /{索引库名}

2.3 文档操作

  • 新增文档:POST  /{索引库名}/_doc/{文档ID}
  • 查询文档:GET  /{索引库名}/_doc/{文档ID}
  • 删除文档:DELETE  /{索引库名}/_doc/{文档ID}
  • 修改文档:
    • 全量修改(根据id先删除再新增相同id的文档 :
      • 语法:PUT /{索引库名}/_doc/{文档id}   参数:js
    •  增量修改:(只修改指定id匹配的文档中的部分字段 :
      •  语法:POST /{索引库名}/_update/{文档id}  参数:js

 

 

2.4 DSL条件查询分类

查询通用语法 :

GET /indexName/_search
{
  "query": {
    "查询类型": {
      "查询条件": "条件值"
    }
  }
}

查询所有 :

  • 全文检索(full text)查询:
    • 使用场景:输入框搜索
    •  match:单字段查询(语法如下) :
    • GET /indexName/_search
      {
        "query": {
          "match": {
            "FIELD": "TEXT"
          }
        }
      }
    • multi_match : 多字段查询,任意一个字段符合条件即可(参与查询字段越多,查询性能越差 ) :
      GET /indexName/_search
      {
        "query": {
          "multi_match": {
            "query": "TEXT",
            "fields": ["FIELD1", " FIELD12"]
          }
        }
      }

  • 精确查询
    •  精确查询一般是查找keyword、数值、日期、boolean等类型字段。不会对搜索条件分词
    • term: 根据词条精确值查询,输入的内容跟自动值完全匹配时才认为符合条件。 
      // term查询
      GET /indexName/_search
      {
        "query": {
          "term": {
            "FIELD": {
              "value": "VALUE"
            }
          }
        }
      }
    • range: 一般应用在对数值类型做范围过滤的时候。比如做价格范围过滤。 
      // range查询
      GET /indexName/_search
      {
        "query": {
          "range": {
            "FIELD": {
              "gte": 10, // 这里的gte代表大于等于,gt则代表大于
              "lte": 20 // lte代表小于等于,lt则代表小于
            }
          }
        }
      }
  • 地理(geo)查询

     

    • 根据经纬度查询,一般用于搜索附近酒店附近人等
    • geo_bounding_box
    • :
      •  矩形范围查询,查询坐标落在某个矩形范围的所有文档,需要指定矩形的左上、右下两个点的坐标,然后画出一个矩形,落在该矩形内的都是符合条件的点。 
        // geo_bounding_box查询
        GET /indexName/_search
        {
          "query": {
            "geo_bounding_box": {
              "FIELD": {
                "top_left": { // 左上点
                  "lat": 31.1,
                  "lon": 121.5
                },
                "bottom_right": { // 右下点
                  "lat": 30.9,
                  "lon": 121.7
                }
              }
            }
          }
        }
    • geo_distance: :  
      •  查询到指定中心点小于某个距离值的所有文档。
        // geo_distance 查询
        GET /indexName/_search
        {
          "query": {
            "geo_distance": {
              "distance": "15km", // 半径
              "FIELD": "31.21,121.5" // 圆心
            }
          }
        }

  • 复合(compound)查询
    • 复合查询可以将其它简单查询组合起来,实现更复杂的搜索逻辑
    • fuction score算分函数查询,可以控制文档相关性算分,控制文档排名
      •  相关性算分:当我们利用match查询时,文档结果会根据与搜索词条的关联度打分(_score),返回结果时按照分值降序排列
        • 算法有TF- IDFBM25算法,es5.1版本后采用BM25
      • 控制相关性算分
        •  语法 :
        • 组成:
          • 原始查询条件:query部分,基于这个条件搜索文档,并且基于BM25算法给文档打分,原始算分(query score)
          • 过滤条件:filter部分,符合该条件的文档才会重新算分(决定哪些文档的算分被修改
          • 算分函数:符合filter条件的文档要根据这个函数做运算,得到的函数算分(function score),有四种函数
            • weight:函数结果是常量
            • field_value_factor:以文档中的某个字段值作为函数结果
            •  random_score:以随机数作为函数结果=
            • script_score:自定义算分函数算法
          • 运算模式:算分函数的结果、原始查询的相关性算分,两者之间的运算方式(决定最终算分结果),包括:
            • multiply:相乘
            • replace:用function score替换query score
            • 其它,例如:sum、avg、max、min
          • 运行流程
            • 1)根据原始条件查询搜索文档,并且计算相关性算分,称为原始算分(query score)
            • 2)根据过滤条件,过滤文档
            • 3)符合过滤条件的文档,基于算分函数运算,得到函数算分(function score)
            • 4)将原始算分(query score)和函数算分(function score)基于运算模式做运算,得到最终结果,作为相关性算分。 
  • bool query布尔查询,利用逻辑关系组合多个其它的查询,实现复杂搜索。布尔查询是一个或多个查询子句的组合,每一个子句就是一个子查询,子查询的组合方式有
    •  must: 必须匹配每个子查询,类似“与”
    •  should:选择性匹配子查询,类似“或”
    • must_not:必须不匹配,不参与算分,类似“非”
    • filter:必须匹配,不参与算分
    • GET /hotel/_search
      {
        "query": {
          "bool": {
            "must": [
              {"term": {"city": "上海" }}
            ],
            "should": [
              {"term": {"brand": "皇冠假日" }},
              {"term": {"brand": "华美达" }}
            ],
            "must_not": [
              { "range": { "price": { "lte": 500 } }}
            ],
            "filter": [
              { "range": {"score": { "gte": 45 } }}
            ]
          }
        }
      }

2.5 搜索结果处理

2.5.1 排序

        elasticsearch默认是根据相关度算分(_score)来排序,但是也支持自定义方式对搜索结果排序

                普通字段排序: :

GET /indexName/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "FIELD": "desc"  // 排序字段、排序方式ASC、DESC
    }
  ]
}

                地理坐标排序: :

GET /indexName/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "_geo_distance" : {
          "FIELD" : "纬度,经度", // 文档中geo_point类型的字段名、目标坐标点
          "order" : "asc", // 排序方式
          "unit" : "km" // 排序的距离单位
      }
    }
  ]
}

2.5.2 分页

        elasticsearch 默认情况下只返回top10的数据。而如果要查询更多数据就需要修改分页参数了。elasticsearch中通过修改from、size参数来控制要返回的分页结果

from从第几个文档开始,size总共查询几个文档。类似于mysql中的 limit ? , ?

基本分页语法: :

GET /hotel/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0, // 分页开始的位置,默认为0
  "size": 10, // 期望获取的文档总数
  "sort": [
    {"price": "asc"}
  

深度分页语法:官方文档

常见分页实现方案

        from + size:

                优点:支持随机翻页

                缺点:深度分页问题,默认查询上限(from + size)是10000

                场景:百度、京东、谷歌、淘宝这样的随机翻页搜索

        after search:

                优点:没有查询上限(单次查询的size不超过10000)

                缺点:只能向后逐页查询,不支持随机翻页

                场景:没有随机翻页需求的搜索,例如手机向下滚动翻页

        scroll:

                优点:没有查询上限(单次查询的size不超过10000)

                缺点:会有额外内存消耗,并且搜索结果是非实时的

                场景:海量数据的获取和迁移。从ES7.1开始不推荐,建议用 after search方案。

2.5.3 高亮:

  实现 :

GET /hotel/_search
{
  "query": {
    "match": {
      "FIELD": "TEXT" // 查询条件,高亮一定要使用全文检索查询
    }
  },
  "highlight": {
    "fields": { // 指定要高亮的字段
      "FIELD": {
        "pre_tags": "<em>",  // 用来标记高亮字段的前置标签
        "post_tags": "</em>" // 用来标记高亮字段的后置标签
      }
    }
  }
}

流程

  1. 给文档中的所有关键字都添加一个标签,例如<em>标签
  2. 页面给<em>标签编写CSS样式

注意事项

  • 高亮是对关键字高亮,因此搜索条件必须带有关键字,而不能是范围这样的查询。
  • 默认情况下,高亮的字段,必须与搜索指定的字段一致,否则无法高亮
  • 如果要对非搜索字段高亮,则需要添加一个属性:required_field_match=false

全部查询条件示例总结


2.6 数据的聚合

2.6.1 种类

桶(Bucket)聚合:用来对文档做分组

        – TermAggregation:按照文档字段值分组,例如按照品牌值分组、按照国家分组

        – Date Histogram:按照日期阶梯分组,例如一周为一组,或者一月为一组

度量(Metric)聚合:用以计算一些值,比如:最大值、最小值、平均值等

        – Avg:求平均值

        – Max:求最大值

        – Min:求最小值

        – Stats:同时求max、min、avg、sum等

管道(pipeline)聚合:其它聚合的结果为基础做聚合

2.7 自动补全 (后续

2.8 数据同步(后续

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

总结很长时间,麻烦给个点赞吧!

 

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mikasa_akm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值