美文网首页ElasticSearch实战笔记
25、ElasticSearch 7.x 近似匹配、混合使用ma

25、ElasticSearch 7.x 近似匹配、混合使用ma

作者: 众神开挂 | 来源:发表于2020-04-09 09:43 被阅读0次

    主要内容:近似匹配、混合使用match和近似匹配、rescoring机制

    1、近似匹配

    1.1、match_phrase 短语查询

    phrase match,就是要去将多个term作为一个短语,一起去搜索,只有包含这个短语的doc才会作为结果返回。

    match_phrase语法

    //将一个doc的content设置为恰巧包含java spark这个短语.
    GET /forum/_search
    {
      "query": {
        "match_phrase": {
          "content": "java spark"
        }
      }
    }
    

    只有包含java spark这个短语的doc才返回了,只包含java的doc不会返回

    1.2、 基于slop参数实现近似匹配

    实战演练

    GET /forum/_search
    {
      "query": {
        "match_phrase": {
          "title": {
            "query": "elasticsearch hadoop",
            "slop": 1
          }
        }
      }
    }
    

    slop的含义是什么?

    slop的含义,:一个query string terms,最多可以移动几次去尝试跟一个doc匹配上

    实验验证slop的含义

    GET /forum/_search
    {
      "query": {
        "match_phrase": {
          "title": {
            "query": "java spark",
            "slop": 3
          }
        }
      }
    }
    

    <u>spark</u> is best big <u>data</u>

    spark data(data右移三次才会匹配)

    案例02:

    data spark 匹配 spark is best big data

    data(右移四次)+spark(左移一次)=共5次

    GET /forum/_search
    {
      "query": {
        "match_phrase": {
          "content": {
            "query": "data spark",
            "slop": 5
          }
        }
      }
    }
    

    slop搜索下,关键词离的越近,relevance score就会越高。

    加了slop的phrase match,就是proximity match,近似匹配

    2、混合使用match和近似匹配实现召回率与精准度的平衡

    召回率 recall 与 精准度 precision的基本概念:

    比如你搜索一个java spark,总共有100个doc,能返回多少个doc作为结果,就是召回率

    比如你搜索一个java spark,能不能尽可能让包含java spark,或者是java和spark离的很近的doc,排在最前面,这就是精准度。

    近似匹配的时候,召回率比较低,精准度太高了

    但是有时可能我们希望的是匹配到几个term中的部分,就可以作为结果出来,这样可以提高召回率。同时我们也希望用上match_phrase根据距离提升分数的功能,让几个term距离越近分数就越高,优先返回

    就是优先满足召回率,意思,java spark,包含java的也返回,包含spark的也返回,包含java和spark的也返回;同时兼顾精准度,就是包含java和spark,同时java和spark离的越近的doc排在最前面

    此时可以用bool组合match query和match_phrase query一起,来实现上述效果

    GET /forum/_search
    {
      "query": {
        "bool": {
          "must": {
            "match": {
              "title": {
                "query": "java spark" #返回所有java spark的结果,但不能区分java和spark的距离
              }
            }
          },
          "should": {
            "match_phrase": {
              "title": {
                "query": "java spark", #在slop以内,增加匹配doc的relevance score
                "slop": 50
              }
            }
          }
        }
      }
    }
    

    查询示例02:

    GET /forum/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "content": "java spark"
              }
            }
          ],
          "should": [
            {
              "match_phrase": {
                "content": {
                  "query": "java spark",
                  "slop": 50
                }
              }
            }
          ]
        }
      }
    }
    

    3、使用rescoring机制优化近似匹配搜索的性能

    3.1、match和phrase match(proximity match)

    match query的性能比phrase match和proximity match(有slop)要高很多。因为后两者都要计算position的距离。
    match query比phrase match的性能要高10倍,比proximity match的性能要高20倍。

    但是别太担心,因为es的性能一般都在毫秒级别,match query一般就在几毫秒,或者几十毫秒,而phrase match和proximity match的性能在几十毫秒到几百毫秒之间,所以也是可以接受的。

    优化proximity match的性能,一般就是减少要进行proximity match搜索的document数量。主要思路就是,用match query先过滤出需要的数据,然后再用proximity match来根据term距离提高doc的分数,同时proximity match只针对每个shard的分数排名前n个doc起作用,来重新调整它们的分数,这个过程称之为rescoring(重打分),重计分。因为一般用户会分页查询,只会看到前几页的数据,所以不需要对所有结果进行proximity match操作。

    用我们刚才的说法,match + proximity match同时实现召回率和精准度

    默认情况下,match也许匹配了1000个doc,proximity match全都需要对每个doc进行一遍运算,判断能否slop移动匹配上,然后去贡献自己的分数
    但是很多情况下,match出来也许1000个doc,其实用户大部分情况下是分页查询的,所以可能最多只会看前几页,比如一页是10条,最多也许就看5页,就是50条
    proximity match只要对前50个doc进行slop移动去匹配,去贡献自己的分数即可,不需要对全部1000个doc都去a进行计算和贡献分数

    match:1000个doc,其实这时候每个doc都有一个分数了; proximity match,前50个doc,进行rescore,重打分,即可; 让前50个doc,term举例越近的,排在越前面

    GET /forum/_search
    {
      "query": {
        "match": {
          "content": "java spark"
        }
      },
      "rescore": {
        "window_size": 50,  ##对前50个打分
        "query": {
          "rescore_query": {
            "match_phrase": {
              "content": {
                "query": "java spark",
                "slop": 50
              }
            }
          }
        }
      }
    }
    

    相关文章

      网友评论

        本文标题:25、ElasticSearch 7.x 近似匹配、混合使用ma

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