美文网首页
ES全文检索基本招式

ES全文检索基本招式

作者: rock_fish | 来源:发表于2020-09-02 17:08 被阅读0次

    一、match

    1. 在执行match查询时,默认情况下,字段值必须匹配任意一个词条,比如文档的eventname字段匹配任意一个分词,azure、aws和cloud时,该文档就匹配
    POST /_search -d
    {  
       "from":10,
       "size":5,
       "query":{  
          "match":{  
             "eventname":"azure aws cloud"
          }
       }
    }
    
    1. 匹配分词的数量是由匹配参数控制的,match查询常用的参数:
    • operator:用来控制match查询匹配词条的逻辑条件,默认值是or,如果设置为and,表示查询满足所有条件;
    • minimum_should_match:当operator参数设置为or时,该参数用来控制应该匹配的分词的最少数量;Elastic控制查询精准度-minimum_should_match
    POST /search -d{  
       "from":10,
       "size":5,
       "query":{  
          "match":{  
             "eventname":{  
                "query":"azure aws cloud security",
                "operator":"or",
                "minimum_should_match":2
             }
          }
       }
    }
    
    POST /search -d{  
       "from":10,
       "size":5,
       "query":{  
          "match":{  
             "eventname":{  
                "query":"azure aws cloud security",
                "operator":"adn"
             }
          }
       }
    }
    
    1. 底层实现的转换 将multi-query 转换为 bool+ must/should + term
      3.1、or
        GET /forum/article/_search
    {
        "query": {
            "match": {
                "title": "java elasticsearch"
            }
        }
    }
    

    相当于:bool should term

    {
      "bool": {
        "should": [
          { "term": { "title": "java" }},
          { "term": { "title": "elasticsearch"   }}
        ]
      }
    }
    

    3.2、and
    如果title字段是analyzed则进行full text全文搜索,则返回title字段包含java 或者elasticsearch 或者两个都包含的document
    如果是not_analyzed则进行exact value(相当于temr query),则只返回包含java elasticsearch的document

    GET /forum/article/_search
    {
        "query": {
            "match": {
                "title": {
            "query": "java elasticsearch",
            "operator": "and"              //full text 中 返回都包含“java”和"elasticsearch“的document
               }
            }
        }
    }
    

    相当于:bool must term

       {
          "bool": {
         "must": [
          { "term": { "title": "java" }},
          { "term": { "title": "elasticsearch"   }}
            ]
          }
        }
    

    3.3、minimum_should_match

    GET /forum/article/_search
    {
      "query": {
        "match": {
          "title": {
            "query": "java elasticsearch spark hadoop",
            "minimum_should_match": "75%"  // full text中返回,包含指定条件的75%的document
          }
        }
      }
    }
    

    相当于:bool should term minimum_should_match

    {
      "bool": {
        "should": [
          { "term": { "title": "java" }},
          { "term": { "title": "elasticsearch"   }},
          { "term": { "title": "hadoop" }},
          { "term": { "title": "spark" }}
        ],
        "minimum_should_match": 3
      }
    }
    

    补充知识点:must和should对分数有影响;must是必须条件,之后should匹配的越多则分数越高
    更多参考:布尔匹配查询

    二、短语匹配查询(match_phrase)

    Elasticsearch - 短语匹配(match_phrase)以及slop参数

    在执行短语匹配查询时,ElasticSearch引擎首先分析(analyze)查询字符串,从分析后的文本中构建短语查询:

    • 必须匹配短语中的所有分词
    • 保证各个分词的相对位置不变
    POST /_search -d
    {  
       "from":1,
       "size":100,
       "fields":[ "eventname"],
       "query":{  
          "match_phrase":{  
             "eventname":"Open Source"
          }
       }
    }
    

    "this is an Open Souce xxx" 匹配
    “Open this Source code xxx" 不匹配

    短语匹配使用slop参数来引入一些灵活性;slop参数告诉match_phrase查询词条能够相隔多远时仍然将文档视为匹配;其中移动可以是反向的,比如这样的场景:Open 左移,Source 又移

    GET /my_index/my_type/_search
    {
        "query": {
            "match_phrase": {
                "title": {
                    "query": "Open Source",
                    "slop":  2
                }
            }
        }
    }
    

    三、 boost条件权重控制

    默认情况下,搜索条件的权重都是一样的,都是1;boost控制搜索条件的权重,可以将某个搜索条件的权重加大,此时当匹配这个搜索条件和匹配另一个搜索条件的document,计算relevance score时,匹配权重更大的搜索条件的document,relevance score会更高,也就会优先被返回。

    GET /forum/article/_search 
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "title": "blog"
              }
            }
          ],
          "should": [
            {
              "match": {
                "title": {
                  "query": "elasticsearch"
                }
              }
            },
            {
              "match": {
                "title": {
                  "query": "spark",
                  "boost": 5
                }
              }
            }
          ]
        }
      }
    }
    

    四、most fields评分算法

    GET /forum/article/_search
    {
        "query": {
            "bool": {
                "should": [
                    { "match": { "title": "java solution" }},
                    { "match": { "content":  "java solution" }}
                ]
            }
        }
    }
    

    按照多个字段的综合匹配情况来计算整体分值,不会因为某个字段的匹配对最高而干扰最终结果,这点是与best fields的区别。
    计算每个document的relevance score:每个query的分数之和,乘以matched query数量,除以总query数量,比如:总共2个match :

    1. doc4的情况是这样:
      doc4 跟match1 部分匹配,有一个"java" 分值1.1
      doc4 跟match2 部分匹配,有一个"solution" 分值1.2
      每个query的分数之和:1.1 + 1.2 = 2.3
      matched query数量 : 2
      总query数量 :2
      2.3 * 2 / 2 = 2.3
    2. doc5的情况是这样
      doc5 跟match1不匹配,没有分值
      doc5 跟match2匹配,匹配度很高,有 "java solution" 分值为2.3
      每个query的分数之和:2.3
      matched query数量 :1
      总query数量 : 2
      2.3 * 1 / 2 = 1.15

    doc5的分数 = 1.15 < doc4的分数 = 2.3

    还有一些内容暂未记录, Elasticsearch顶尖高手系列课程之高手进阶篇

    五、best fields策略

    搜索到的结果,应该是某一个field中匹配到了尽可能多的关键词,被排在前面;而不是尽可能多的field匹配到了少数的关键词,排在了前面

    dis_max语法,直接取多个query中,分数最高的那一个query的分数,完全不考虑其他字段的分数

    GET /forum/article/_search
    {
        "query": {
            "dis_max": {
                "queries": [
                    { "match": { "title": "java solution" }},
                    { "match": { "content":  "java solution" }}
                ]
            }
        }
    }
    
    1.使用tie_breaker 优化 dis_max

    使用tie_breaker将其他query的分数也考虑进去

    tie_breaker参数的意义,在于说,将其他query的分数,乘以tie_breaker,然后综合与最高分数的那个query的分数,综合在一起进行计算
    除了取最高分以外,还会考虑其他的query的分数
    tie_breaker的值,在0~1之间,是个小数,就ok

    GET /forum/article/_search
    {
        "query": {
            "dis_max": {
                "queries": [
                    { "match": { "title": "java beginner" }},
                    { "match": { "body":  "java beginner" }}
                ],
                "tie_breaker": 0.3
            }
        }
    }
    

    更多参考: Elasticsearch顶尖高手系列课程之高手进阶篇

    相关文章

      网友评论

          本文标题:ES全文检索基本招式

          本文链接:https://www.haomeiwen.com/subject/xxulsktx.html