• ElasticSearch-Query DSL(Domain Specific Language)


    概述

    查询上下文

    使用query关键字进行检索,倾向于相关度搜索,故需要计算评分。搜索是ES最关键和重要的部分。

    相关度评分:_score

    概念:相关度评分用于对搜索结果排序,评分越高则认为其结果和搜索的预期值相关度越高,即越符号预期值。在7.x之前相关度评分默认使用TF/IDF算法计算而来,7.x之后默认使用BM25。
    排序:相关度评分为搜索结果的排序依据,默认情况下评分越高,则结果越靠前。

    元数据:_source

    1. 禁用_source:
      1. 好处:节省存储开销。
      2. 坏处:
        • 不支持update、update_by_query和reindex API。
        • 不支持高亮。
        • 不支持reindex、更改mapping分析器和版本升级。
        • 通过查看索引时使用的原始文档来调试查询或聚合的功能。
        • 将来有可能自动修复索引损坏。
          总结:如果只是为了节省磁盘,可以采用压缩索引比禁用_source更好。
    2. 数据源过滤器
      including:结果中返回哪些field
      excluding:结果中不要返回哪些field,不返回的field不代表不能通过该字段进行检索,因为元数据不存在不代表索引不存在。
      • 在mapping中定义过滤,支持通配符,但是这种方式不推荐,因为mapping不可变。
    PUT product
    {
      "mappings": {
        "_source": {
          "includes": [
            "name",
            "price"
          ],
          "excludes": [
            "desc",
            "tags"
          ]
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 常用过滤规则
      1. “_source”:“false”
      2. “_source”:“obj.*”
      3. “_source”:[“obj1.*”,“xxx”],
      4. “_source”:{
        “includes”: [“field1”,“field2”],
        “excludes”:[“xxx”,“xxx”]
        }

    Query String

    • 查询所有
    GET /product/_search
    
    • 1
    • 带参数
    GET /product/_search?q=name:xiaomi
    
    • 1
    • 分页
    - GET /product/_search?from=0&size=2&sort=price:asc
    
    • 1
    • 精准匹配 exact value
    GET /product/_search?q=date:2021-06-01
    
    • 1
    • _all 搜索 相当于在所有有索引的字段中检索
    GET /product/_search?q=2021-06-01
    
    • 1

    全文检索-fulltext query

    语法:

    GET index/_search
    {
      "query": {
        ***
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    match:匹配包含某个term(词项)的子句,相对mysql中的模糊匹配

    下面示例中"xiaomi nfc phone" 会被拆分成3个词项,满足任何一个词项的doc,都会被搜索出来。

    GET /product/_search
    {
      "query": {
        "match": {
          "name": "xiaomi nfc phone"
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    match_all:匹配所有结果的子句

    GET /product/_search
    {
      "query": {
        "match_all": {}
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    multi_match:多字段条件

    在多个字段中查询,一个字段中包含查询条件就搜索出,match只是在一个字段中查询。

    GET /product/_search
    {
      "query": {
        "multi_match": {
          "query": "phone",
          "fields": ["name", "desc"]
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    match_phrase:短语查询

    查询的字段中必须包含该短语。

    GET /product/_search
    {
      "query": {
        "match_phrase": {
          "name": "xiaomi nfc"
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    精准查询

    term:匹配和搜索词项完全相等的结果

    也就是搜索的字段中必须包含指定的词项,且term指定的就是完整的词项,不会向match那样进行拆分。

    GET /product/_search
    {
      "query": {
        "term": {
          "name": {
            "value": "nfc"
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • term和match_phrase区别:
      match_phrase会将检索关键词分词,match_phrase的分词结果必须被检索字段的分词中都包含,而且顺序必须相同,而且默认必须都是联系的。
      term搜索不会将搜索词分词。
    • term和keyword区别
      term是对于搜索词不分词。
      keyword是字段类型,是对于source data中的字段不分词,是一个完整的词项。
    GET /product/_search
    {
      "query": {
        "term": {
          "name.keyword": {
            "value": "xiaomi nfc phone"
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    terms:匹配和搜索词项列表中任意项匹配的结果

    term是搜索字段包含其中的词项即可,terms是指搜索字段中只要包含其中的一个词项即可,也就是terms中可以包含多个词项。

    GET /product/_search
    {
      "query": {
        "terms": {
          "name": [
            "phone",
            "xiaomi"
          ]
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    range:范围查找

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

    filter 查询

    filter查询的性能比query要高,主要原因是filter查询对结果不在进行评分,减少了评分所消耗的时间。
    示例如下:

    // 给定具体的评分,不给定默认是1分
    GET /product/_search
    {
      "query": {
        "constant_score": {
          "filter": {
            "match": {
              "name": "huawei"
            }
          }
          "boost":1
        }
      }
    }
    // 放在组合查询中
    GET /product/_search
    {
      "query": {
        "bool": {
          "filter": [
            {
              "term": {
                "name": "huawei"
              }
            }
          ]
        }
      }
    }
    
    • 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

    filter与query的主要区别

    filter是结果导向的,速度更快,而query是过程导向的。
    query倾向于“当前文档和查询的语句的相关度”,而filter倾向于“当前文档和查询到条件是不是相符”。即在查询过程中,query是要对查询的每个结果计算相关性得分的,而filter不会。另外filter有相应的缓存机制,可以提高查询效率。

    组合查询-Bool query

    bool:可以组合多个查询条件,bool查询也是采用more_matches_is_better的机制,bool组合的条件之间通过and结合起来。
    因此满足must和should子句的文档会合并起来计算分值。

    • must:必须满足子句(查询)必须出现在匹配的文档中,并将有助于得分。
    • filter:过滤器,不计算相关度分数,子句(查询)必须出现在匹配的文档中,与must类似。但是不像must查询那样计算分数。Filter子句在filter上下文中执行,这意味着计分被忽略,并且子句被考虑用于缓存。
    • should:可能满足,相当于or子句(查询)满足其中一个条件即可查询出匹配的文档。
    • must_not:必须不满足,不计算相关度分数,not子句(查询)不得出现在匹配的文档中。子句在过滤器上下文中执行,这意味着计分被忽略,并且子句被视为用于缓存。由于忽略计分,因此所以匹配的文档分数都是0。
    • minimum_should_match:参数指定should返回的文档必须匹配的子句的数量或百分比。如果bool查询包含至少一个should子句,而没有must或filter子句,则默认为1,否则,默认值为0。
    GET /product/_search
    {
      "query": {
        "bool": {
          "filter": [
            {
              "match":{
                "name": "phone"
              }
            }
          ],
          "should": [
            {
              "match_phrase": {
                "name": "xiaomi phone"
              }
            }
          ],
          "minimum_should_match": 1
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
  • 相关阅读:
    机器学习强基计划2-3:图文详解决策树预剪枝、后剪枝原理+Python实现
    Docker运维,基础
    用宝塔部署静态html页面
    大数据Presto(三):Presto Connector连接器
    linux系统下安装Zookeeper详细教程
    Fastjson tomcat-dhcp链
    springboot充电桩综合管理系统
    Paypal发布公开信,三月已过,PYUSD发展如何?
    VSCODE配置C和C++
    感冒会引发腺样体肥大吗?
  • 原文地址:https://blog.csdn.net/tianzhonghaoqing/article/details/127953977