近似匹配
假设现在有两个document,他们的content的值分别是:
java is my favourite programming language, and I also think spark is a very good big data system.
java spark are very related, because scala is spark’s programming language and scala is also based on jvm like java.
用一个match query去搜索java spark
1 | { |
match query的话,只能搜索到包含java或者包含spark的document,但是不知道java和spark是不是离的很近
包含java或者包含spark的document都会被返回回来.我们其实并不知道哪个document中java和spark距离的比较近.
如果我们是希望搜索java和spark,中间没有任何其他的字符,那么这时候用match匹配做全文检索肯定就不行了.
如果说我们要尽量让java和spark离的很近的document优先返回,要给他一个更高的relevance score,这就涉及到了proximity match 近似匹配.
如果现在有两个需求:
- java spark,要连在一起,中间没有任何字符
- java spark,不需要连在一起,但是这两个单词靠的越近,doc的分数越高,排名越靠前
要实现上面两个需求,用match做全文检索是搞不定的. 必须得用proximity match,近似匹配
phrase match(短语匹配),proximity match(近似匹配)
本文主要说的是 phrase match,就是仅仅搜索出java和spark靠在一起的那些doc,比如有个doc,是java use’d spark这样是不行的,必须是比如java spark are very good friends,是可以搜索出来的.
phrase match: 就是将多个term作为一个短语,一起去搜索,只有包含这个短语的document才会作为返回结果.
案例
先用match query全文检索搜索一下java spark
1 | GET /forum/article/_search |
包含java和spark的都被返回来了,不是我们想要的结果,然后修改id是5的这个document的content,因为现在的数据没有符合我们要求的
1 | POST /forum/article/5/_update |
然后来用phrase match搜索
1 | GET /forum/article/_search |
返回值:
1 | { |
就是我们刚刚修改的那条数据,只有包含了java spark这个短语的document才返回了,其他的数据不会返回
原理
term position
比如现在有两个document的content值如下:
document1: hello world, java spark
document2: hi, spark java
对上面的数据进行分词,然后会记录每个词在每个doc中出现的位置
word | term position |
---|---|
hello | doc1(0) |
word | doc1(1) |
java | doc1(2) doc2(2) |
spark | doc1(3) doc2(1) |
我们可以用分词器来看一下
1 | GET _analyze |
返回值:
1 | { |
position就是每个词在句子中所在的位置
match_phrase搜索原理:
用java spark在上面的两个document中进行搜索
java对应的是doc1(2) doc2(2),spark对应的是doc1(3) doc2(1)
要求一个doc,必须包含每个term,才能拿出来继续计算
首先看doc1:在document1中 spark的position比java的position大1,java的position是2,spark的position是3,满足条件
然后看下doc2:在document2中 java position是2,spark position是1,spark position比java position小1,而不是大1,所以doc2不匹配