使用了TF/IDF的标准全文搜索将文档,或者至少文档中的每一个字段,视做"一大袋的单词"(Big bag of Words)。match查询可以告诉咱们这个袋子中是否包含了咱们的搜索词条,可是这只是一个方面。它不能告诉咱们关于单词间关系的任何信息。html
考虑如下这些句子的区别:elasticsearch
一个使用了sue alligator的match查询会匹配以上全部文档,可是它没法告诉咱们这两个词是否表达了部分原文的部分意义,或者是表达了完整的意义。ide
理解单词间的联系是一个复杂的问题,咱们也没法仅仅依靠另外一类查询就解决这个问题,可是咱们至少能够经过单词间的距离来判断单词间可能的关系。ui
真实的文档也许比上面几个例子要长的多:Sue和alligator也许相隔了几个段落。也许咱们仍然但愿包含这样的文档,可是咱们会给那些Sue和alligator出现的较近的文档更高的相关度分值。spa
这就是短语匹配(Phrase Matching),或者邻近度匹配(Proximity Matching)。code
TIPhtm
本章中,咱们仍然会使用match查询中使用的示例文档。索引
就像一提到全文搜索会首先想到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:
若是以上的任何条件没有被知足,那么文档就不能被匹配。
TIP
在内部,match_phrase查询使用了低级的span查询族(Query Family)来执行位置感知的查询。span查询是词条级别的查询,所以它们没有解析阶段(Analysis Phase);它们直接搜索精确的词条。
幸运的是,大多数用户几乎不须要直接使用span查询,由于match_phrase查询一般已经够好了。可是,对于某些特别的字段,好比专利搜索(Patent Search),会使用这些低级查询来执行拥有很是特别构造的位置搜索。
精确短语(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