zoukankan      html  css  js  c++  java
  • [Elasticsearch] 邻近匹配 (一)

    本文翻译自Elasticsearch官方指南的Proximity Matching一章。


    邻近匹配(Proximity Matching)

    使用了TF/IDF的标准全文搜索将文档,或者至少文档中的每一个字段,视作"一大袋的单词"(Big bag of Words)。match查询可以告诉我们这个袋子中是否包括了我们的搜索词条,可是这仅仅是一个方面。它不能告诉我们关于单词间关系的不论什么信息。

    考虑下面这些句子的差别:

    • Sue ate the alligator.
    • The alligator ate Sue.
    • Sue never goes anywhere without her alligator-skin purse.

    一个使用了sue alligator的match查询会匹配以上全部文档,可是它无法告诉我们这两个词是否表达了部分原文的部分意义,或者是表达了完整的意义。

    理解单词间的联系是一个复杂的问题,我们也无法只依靠还有一类查询就解决问题,可是我们至少能够通过单词间的距离来推断单词间可能的关系。

    真实的文档或许比上面几个样例要长的多:Sue和alligator或许相隔了几个段落。或许我们仍然希望包括这种文档,可是我们会给那些Sue和alligator出现的较近的文档更高的相关度分值。

    这就是短语匹配(Phrase Matching),或者邻近度匹配(Proximity Matching)。

    TIP

    本章中,我们仍然会使用match查询中使用的演示样例文档。



    短语匹配(Phrase Matching)

    就像一提到全文搜索会首先想到match查询一样,当你须要寻找邻近的几个单词时,你会使用match_phrase查询:

    GET /my_index/my_type/_search
    {
        "query": {
            "match_phrase": {
                "title": "quick brown fox"
            }
        }
    }

    和match查询类似,match_phrase查询首先解析查询字符串来产生一个词条列表。然后会搜索全部的词条,但仅仅保留含有了全部搜索词条的文档,而且词条的位置要邻接。一个针对短语quick fox的查询不会匹配我们的不论什么文档,由于没有文档含有邻接在一起的quick和box词条。

    TIP

    match_phrase查询也能够写成类型为phrase的match查询:

    "match": {
        "title": {
            "query": "quick brown fox",
            "type":  "phrase"
        }
    }

    词条位置

    当一个字符串被解析时,解析器不仅仅仅返回一个词条列表,它同一时候也返回每一个词条的位置,或者顺序信息:

    GET /_analyze?analyzer=standard
    Quick brown fox

    会返回下面的结果:

    {
       "tokens": [
          {
             "token": "quick",
             "start_offset": 0,
             "end_offset": 5,
             "type": "<ALPHANUM>",
             "position": 1 
          },
          {
             "token": "brown",
             "start_offset": 6,
             "end_offset": 11,
             "type": "<ALPHANUM>",
             "position": 2 
          },
          {
             "token": "fox",
             "start_offset": 12,
             "end_offset": 15,
             "type": "<ALPHANUM>",
             "position": 3 
          }
       ]
    }

    位置信息可以被保存在倒排索引(Inverted Index)中,像match_phrase这样位置感知(Position-aware)的查询可以使用位置信息来匹配那些含有正确单词出现顺序的文档,在这些单词间没有插入别的单词。

    短语是什么

    对于匹配了短语"quick brown fox"的文档,以下的条件必须为true:

    • quick,brown和fox必须所有出如今某个字段中。
    • brown的位置必须比quick的位置大1。
    • fox的位置必须比quick的位置大2。

    假设以上的不论什么条件没有被满足,那么文档就不能被匹配。

    TIP

    在内部,match_phrase查询使用了低级的span查询族(Query Family)来运行位置感知的查询。span查询是词条级别的查询,因此它们没有解析阶段(Analysis Phase);它们直接搜索精确的词条。

    幸运的是,大多数用户差点儿不须要直接使用span查询,由于match_phrase查询通常已经够好了。可是,对于某些特别的字段,比方专利搜索(Patent Search),会使用这些低级查询来运行拥有很特别构造的位置搜索。



    混合起来(Mixing it up)

    精确短语(Exact-phrase)匹配或许太过于严格了。或许我们希望含有"quick brown fox"的文档也可以匹配"quick fox"查询,即使位置并非全然相等的。

    我们能够在短语匹配使用slop參数来引入一些灵活性:

    GET /my_index/my_type/_search
    {
        "query": {
            "match_phrase": {
                "title": {
                    "query": "quick fox",
                    "slop":  1
                }
            }
        }
    }

    slop參数告诉match_phrase查询词条可以相隔多远时仍然将文档视为匹配。相隔多远的意思是,你须要移动一个词条多少次来让查询和文档匹配?

    我们以一个简单的样例来阐述这个概念。为了让查询quick fox可以匹配含有quick brown fox的文档,我们须要slop的值为1:

                Pos 1         Pos 2         Pos 3
    -----------------------------------------------
    Doc:        quick         brown         fox
    -----------------------------------------------
    Query:      quick         fox
    Slop 1:     quick                 ↳     fox
    

    虽然在使用了slop的短语匹配中,全部的单词都须要出现,可是单词的出现顺序能够不同。假设slop的值足够大,那么单词的顺序能够是随意的。

    为了让fox quick查询可以匹配我们的文档,须要slop的值为3:

                Pos 1         Pos 2         Pos 3
    -----------------------------------------------
    Doc:        quick         brown         fox
    -----------------------------------------------
    Query:      fox           quick
    Slop 1:     fox|quick  ↵  
    Slop 2:     quick      ↳  fox
    Slop 3:     quick                 ↳     fox



  • 相关阅读:
    Java如何让线程池满后再存放队列
    Java如何让线程池满后再存放队列
    Hystrix 中线程池隔离与信号量隔离区别
    微服务中服务间feign调用header传参
    JVM 垃圾收集器
    java对象引用与垃圾收集器回收算法
    JVM 中 java 对象布局
    类加载器与双亲委派机制
    sql 查询本周周一与周日时间
    VUE组件循环引用
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4314336.html
Copyright © 2011-2022 走看看