[Elasticsearch] 邻近匹配 (一) - 短语匹配以及slop参数

邻近匹配(Proximity Matching)

 

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

考虑如下这些句子的区别:elasticsearch

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

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

理解单词间的联系是一个复杂的问题,咱们也没法仅仅依靠另外一类查询就解决这个问题,可是咱们至少能够经过单词间的距离来判断单词间可能的关系。ui

真实的文档也许比上面几个例子要长的多:Sue和alligator也许相隔了几个段落。也许咱们仍然但愿包含这样的文档,可是咱们会给那些Sue和alligator出现的较近的文档更高的相关度分值。spa

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

TIPhtm

本章中,咱们仍然会使用match查询中使用的示例文档。索引

 

 

 

短语匹配(Phrase Matching)

 

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

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:

 
  1. Pos 1 Pos 2 Pos 3

  2. -----------------------------------------------

  3. Doc: quick brown fox

  4. -----------------------------------------------

  5. Query: quick fox

  6. Slop 1: quick ↳ fox

尽管在使用了slop的短语匹配中,全部的单词都须要出现,可是单词的出现顺序能够不一样。若是slop的值足够大,那么单词的顺序能够是任意的。

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

 
  1. Pos 1 Pos 2 Pos 3

  2. -----------------------------------------------

  3. Doc: quick brown fox

  4. -----------------------------------------------

  5. Query: fox quick

  6. Slop 1: fox|quick ↵

  7. Slop 2: quick ↳ fox

  8. Slop 3: quick ↳ fox

相关文章
相关标签/搜索