您的位置:首页 > 运维架构

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

2015-03-04 21:18 218 查看
本文翻译自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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: