• elasticsearh中查询类型,term、match、match_all、multi_match、range、bool、boosting等


    查询方式有如下几种:
    GET //_search
    GET /_search
    POST //_search
    POST /_search
    
    • 1
    • 2
    • 3
    • 4

    一般分为如下几类查询:

    • 叶子查询语句,如:match,term,range 可以单独使用
    • 复合查询语句,组合多个叶子、复合查询为一个查询,例如:booldis_maxconstant_score
    • 昂贵的子查询,一般比较耗时的查询,比如script queriesfuzzy queriesregexp queries

    返回查询结果示例说明:

    {
      "took" : 159,             //响应时间,毫秒
      "timed_out" : false,      // 是否超时
      "_shards" : {             // 分片信息
        "total" : 5,            //总数
        "successful" : 5,       //成功
        "skipped" : 0,          //忽略
        "failed" : 0            // 失败
      },
      "hits" : {                //搜索命中结果
        "total" : {             //搜索条件匹配的文档总数
          "value" : 1,          // 总命中计数的值
          "relation" : "eq"     // 计数规则,eq表示准确,qte表示不准确
        },
        "max_score" : 1.0,      //匹配度分之
        "hits" : [              // 命中结果集合
          {
            "_index" : "goods_info",
            "_type" : "_doc",
            "_id" : "1",
            "_score" : 1.0,
            "_source" : {
              "doc" : {
                "name" : "ThinkPad 联想 E14 11代i5/I7 2G独显 轻薄便携商务办公学生网课IBM笔记本电脑 i7-1165G7 32G内存 1T固态 定制 2G独显 WiFi6 FHD屏幕 雷电接口"
              }
            }
          }
        ]
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    match_all查询

    match_all没有任何条件,检索文档全部数据,但是可以进行一些排序之类的

    match查询

    匹配查询,会将查询条件进行分词,然后进行查询, 多个分词后查询的关系是or

    GET /goods_info/_search
    {
      "query": {
        "match": {
          "name": "华为电脑"
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这里是es官方关于match查询的详细介绍match查询,其中我们可以看到,有一个operator选项,在这里我们可以指定分词后查询的关系,默认是上面or,表示指定的查询语分词后只要匹配到其中一个就行,还有一个是and表示必须匹配到所有的分词:

    GET /goods_info/_search
    {
      "query": {
        "match": {
          "detail": {
            "query": "华为笔记本电脑",
            "operator": "and"
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    这里可以对比下查询后和上面默认的or选项的差别。
    同时在查询的时候我们可以指定查询条件的关键词的分词器,通过analyzer参数指定。

    GET /goods_info/_search
    {
      "query": {
        "match": {
          "detail": {
            "query": "华为笔记本电脑",
            "analyzer": "standard", 
            "operator": "and"
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    multi_match查询

    与match类似,不同的是可以在多个字段中查询:

    GET /goods_info/_search
    {
      "query": {
        "multi_match": {
          "query": "华为电脑",
          "fields": ["name","detail"]
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    term精确查询

    term关键字查询,精确匹配,不会对查询条件进行分词:
    例如:

    GET /goods_info/_search
    {
      "query": {
        "term": {
          "brand": {
            "value": "笔记本"
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    term查询有点类似SQL中的等值查询,上面的match有点类似SQL中的like模糊匹配。
    这个时候如果我们用term去查询name字段,将查询不到信息:

    GET /goods_info/_search
    {
      "query": {
        "term": {
          "name": {
            "value": "笔记本"
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    但是match查询则是可以。

    terms多关键字精确查询

    terms支持多个关键字精确查询:

    GET /goods_info/_search
    {
      "query": {
        "terms": {
          "brand": [
            "笔记本",
            "手机"
          ]
        }
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    range范围查询

    range可以进行范围查询,比如日期,价格:

    GET /goods_info/_search
    {
      "query": {
        "range": {
          "price": {
            "gte": 4000,
            "lte": 6000
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    这里我们查询电脑价格在4000到6000价格区间的商品.
    range查询中:

    • gt 大于
    • gte 大于等于
    • lt 小于
    • lte小于等于
    match_phrase查询

    match_phrase查询主要特性在如下两点:

    1. 查询条件分词后都必须匹配,类似match中的operator=and
    2. 文档匹配的顺序必须与查询条件分词匹配后一致

    这是官方介绍地址match_phrase

    match_phrase_prefix查询

    match_phrase_prefix基本上和match_phrase查询差不多,但是会对查询条件分词后的最后一个词项进行prefix前缀匹配查询

    match_bool_prefix查询

    match_bool_prefix查询类似于match_phrase_prefix,不同的是,match_bool_prefix没有对查询条件分词后匹配的顺序有限制。

    intervals查询

    intervals允许用户精确控制查询词在文档中出现的先后关系,实现了对terms顺序、terms之间的距离以及它们之间的包含关系的灵活控制,通过intervals query(间隔搜索) 我们可以完成各个terms在于不同位置的灵活搜索

    query_string查询

    query_string查询是一个贴近于luncene语法的查询,可以在一个查询中使用多个特殊关键字(如AND |OR|NOT),需要熟悉lucene语法

    simple_query_string查询

    simple_query_string查询与query_string查询类似,但是提供更多的选项

    bool查询

    boot查询是一个复合多条件查询,可以指定多个查询条件

    POST _search
    {
      "query": {
        "bool" : {
          "must" : {
            "term" : { "user.id" : "kimchy" }
          },
          "filter": {
            "term" : { "tags" : "production" }
          },
          "must_not" : {
            "range" : {
              "age" : { "gte" : 10, "lte" : 20 }
            }
          },
          "should" : [
            { "term" : { "tags" : "env1" } },
            { "term" : { "tags" : "deployed" } }
          ],
          "minimum_should_match" : 1,
          "boost" : 1.0
        }
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    可以指定如下几个条件:

    • must 必须满足条件,会增加_score评分
    • must not必须不满足
    • should 满不满足无所谓,但是如果满足会增加_score评分,主要用于修正文档的相关性评分
    • filter 必须满足条件,但是不会增加评分
      比如查询笔记本电脑但不要显示苹果相关产品,优先展示2022-08-01之后上的产品

    Filter和Query的区别:

    • filter和must_not属于Filter Context,不会对_score结果产生影响;
    • must和should属于Query Context,会对_score结果产生影响
    boosting查询

    boosting用来调节查询的_score分值,有如下几个分值调节选项:

    • positive必须匹配上,匹配上会放入返回的结果列表
    • negative 匹配上positive在匹配上negative的文档会被减分
    • negative_boost减分的系数,0到1之间,如果negative匹配上之后,这时候会将negative匹配的文档分数乘以negative_boost的系数
    GET /goods_info/_search
    {
      "query": {
        "boosting": {
          "positive": {
            "match": {
              "name": "笔记本电脑"
            }
          }
          , "negative": {
            "match": {
              "detail": "苹果"
            }
          }
          , "negative_boost": 0.2
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    这里我们依旧查询笔记本电脑,但是如果商品是包含苹果关键字,则会降低评分.
    详细见: boosting query

    constant_score查询

    constant_score查询会忽略文档默认的_score相关性评分,而是采用一个统一固定的评分,默认是1.0。

    GET /goods_info/_search
    {
      "query": {
        "constant_score": {
          "filter": {
            "term": {
              "brand": "笔记本"
            }
          },
          "boost": 1.2
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    返回的匹配文档的_score会设置为指定的boost评分

    dis_max查询

    dis_max查询可以指定多个查询条件,这些查询条件之间是or的关系,但是针对不同条件可以指定不同的boost算分,将查询结果的最大分数优先返回,除了最大分数,还会讲除最大分数外的其他结果的分数和tie_breaker相乘并和最大分数比较,看哪个大。

    GET /goods_info/_search
    {
      "query": {
        "dis_max": {
          "tie_breaker": 0.7,
          "queries": [
            {
              "match": {
                "name": "笔记本"
              }
            },
            {
              "match": {
                "detail": {
                  "query": "华为",
                  "boost": 1.5
                }
              }
            }
          ]
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    详见: dis_max query

    function_score查询

    function_score查询提供了让用户自定义匹配查询结果的相关性评分,提供了如下几组自定义评分机制:

    • script_score
    • weight
    • random_score
    • field_value_factor
    • decay functions: gauss, linear, exp
      详见:score-functions
    exists查询

    对于指定的查询,过滤返回的结果的某个索引字段必须有值
    类似如下查询:

    GET /goods_info/_search
    {
      "query": {
        "exists": {
          "field":"name"
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这里查询的是所有索引必须name字段有值。一般会和其他查询条件组合使用:

    
    GET /goods_info/_search
    {
      "query": {
        "bool": {
          "should": {
            "match": {
              "name": "笔记本"
            }
          },
          "must": {
            "exists": {
              "field": "brand"
            }
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    这里查询商品必须品牌不为空,在这个条件下,商品名称匹配笔记本
    需要注意的是,exists是属于term查询,不会进行分词

    fuzzy查询

    fuzzy查询有点类似于模糊匹配的功能,但是ES能够对待匹配的值进行一些修成,比如appla能够进行修正匹配文档中的apple

    GET /goods_info/_search
    {
      "query": {
        "fuzzy": {
          "detail": {
            "value": "thinkpadjk",
            "prefix_length": 0
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    详见: fuzzy query

    ids查询

    根据给定的文档id查询

    GET /goods_info/_search
    {
      "query": {
        "ids": {
          "values": [1,2,3,4,5,6]
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    prefix查询

    prefix查询包含指定的前缀内容

    GET /goods_info/_search
    {
      "query": {
        "prefix": {
          "brand": {
            "value": "笔记"
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    wildcard查询

    wildcard是可以使用通配符的查询,类似于SQL中like功能

    GET /goods_info/_search
    {
      "query": {
        "wildcard": {
          "brand": "*笔记*"
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    但是需要注意的是使用wildcard查询的字段必须是keyword类型
    另外就是wildcard查询比较耗费性能。

    regexp查询

    regexp查询正则表达式查询

    指定返回字段

    默认情况下,ES会把匹配到的文档在_source中的字段都返回,我们可以在请求中通过_source返回指定的字段:

    
    GET /goods_info/_search
    {
      "_source": ["name","detail"], 
      "query": {
        "match": {
          "name": "华为电脑"
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    另外我们可以在_source通过includesexcludes来指定想要显示和不想要显示的字段:

    GET /goods_info/_search
    {
      "_source":{
        "includes": ["name","detail"]
      },
      "query": {
        "match": {
          "name": "华为电脑"
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    通过excludes指定不想要现实字段:

    GET /goods_info/_search
    {
      "_source":{
        "excludes": ["name","detail"]
      },
      "query": {
        "match": {
          "name": "华为电脑"
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    collapse返回结果折叠

    collapse关键字会对返回的结果,按照sort排序后只取第一条。

    GET /goods_info/_search
    {
      "query": {
        "match": {
          "name": "笔记本电脑"
        }
      },
      "collapse": {
        "field": "brand"
      },
      "sort": [
        {
          "create_time": {
            "order": "desc"
          }
        }
      ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    这里我们查询华为笔记本电脑,返货结果按照create_time排序,并且通过collapse每个brand只取排序后的数据的第一条。

    highlight高亮显示返回结果

    我们可以针对返回的某些字段增加额外的标签,达到高亮显示效果,ES会对查询的条件分词后再结果字段匹配的部分增加标签:

    GET /goods_info/_search
    {
      "query": {
        "match": {
          "name": "华为笔记本电脑"
        }
      }
     , "highlight": {
       "pre_tags": "",
       "post_tags": "",
       "fields": {"name":{}}
     } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    选取其中一条结果查看:

     {
            "_index" : "goods_info",
            "_type" : "_doc",
            "_id" : "8",
            "_score" : 2.3662727,
            "_source" : {
              "name" : "华为笔记本电脑MateBook D 14 2022 12代酷睿版 i5 16G 512G 锐炬显卡/轻薄本/14英寸护眼全面屏/超级终端 灰",
              "detail" : "华为笔记本电脑MateBook D 14 2022 12代酷睿版 i5 16G 512G 锐炬显卡/轻薄本/14英寸护眼全面屏/超级终端 灰",
              "brand" : "笔记本",
              "price" : 5299,
              "sales_count" : 100000,
              "picture" : "https://item.jd.com/100039356468.html",
              "click_url" : "https://item.jd.com/100039356468.html",
              "create_time" : "2022-08-14"
            },
            "highlight" : {
              "name" : [
                "MateBook D 14 2022 12代酷睿版 i5 16G 512G 锐炬显卡/轻薄/14英寸护眼全面屏/超级终端 灰"
              ]
            }
          }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    详见 highlighting

    分页查询

    在查询的时候我们可以通过fromsize来对结果进行分页:

    GET /goods_info/_search
    {
      "query": {
        "match": {
          "name": "华为笔记本电脑"
        }
      },
      "from": 0,
      "size": 2
      
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    from默认从0开始,size是每页的大小。
    需要注意的是,默认情况下,使用分页,也不能查询超过10000条数据

    如果需要分页查询更多的数据,那么可以使用scroll或者search_after

    详见paginate-search-results

  • 相关阅读:
    面试官:告诉我为什么static和transient关键字修饰的变量不能被序列化?
    SpringMVC详解
    信号与线性系统分析(吴大正,郭宝龙)(信号的分类)
    提升机器视觉与机器学习软件安全性的实践策略
    Positive Technologies 在迪拜宣布与地区网络安全解决方案提供商开展合作
    数据结构与算法
    r语言绘制动态统计图:绘制世界各国的人均GDP,出生时的期望寿命和人口气泡图动画动态gif图
    软件测试之如何提升产品的用户体验度
    基于大模型的剧本创作实践;从互联网转行AIGC经验分享;复旦大学LLM最新教科书(电子版);真格基金被投企业2023秋季联合校招 | ShowMeAI日报
    【阅读笔记】Java游戏服务器架构实战(待更新)
  • 原文地址:https://blog.csdn.net/LeoHan163/article/details/126433158