當前位置:編程學習大全網 - 源碼下載 - es使用與原理4 -- phrase match ,slop近似匹配,搜索推薦等等

es使用與原理4 -- phrase match ,slop近似匹配,搜索推薦等等

match query,只能搜索到包含java和spark的document,但是不知道java和spark是不是離的很近

包含java或包含spark,或包含java和spark的doc,都會被返回回來。我們其實並不知道哪個doc,java和spark距離的比較近。如果我們就是希望搜索java spark,中間不能插入任何其他的字符 或者指定中間只能隔num個字符,那這個時候match去做全文檢索,能搞定我們的需求嗎?答案是,搞不定。

兩個需求:

1、java spark,就靠在壹起,中間不能插入任何其他字符,就要搜索出來這種doc

2、java spark,但是要求,java和spark兩個單詞靠的越近,doc的分數越高,排名越靠前

phrase match 就是短語匹配,將短語作為壹個整體去查找。

3、分詞後的臨時 position

從結果中,我們可以看出 hello的臨時位置是0,world, java spark 的位置依次是 1,2,3

4、短語搜索的原理(近似搜索的原理也是這樣的)

hello world, java spark doc1

hi, spark java doc2

hello doc1(0)

wolrd doc1(1)

java doc1(2) doc2(2)

spark doc1(3) doc2(1)

java spark --> match phrase

java spark --> java和spark

java --> doc1(2) doc2(2)

spark --> doc1(3) doc2(1)

要找到每個term都在的壹個***有的那些doc,就是要求壹個doc,必須包含每個term,才能拿出來繼續計算

doc1 --> java和spark --> spark position恰巧比java大1 --> java的position是2,spark的position是3,恰好滿足條件 ,doc1符合條件

doc2 --> java和spark --> java position是2,spark position是1,spark position比java position小1,而不是大1 --> 光是position就不滿足,那麽doc2不匹配

類似的 近似搜索原理也是這樣的

slop的含義是什麽? 搜索文本,中的幾個term,要經過幾次移動才能與壹個document匹配,這個移動的次數,就是slop。簡單的說就是 java 和 spark之間的距離 或者java和spark交換後的距離+2(這裏的2是交換所需要的步數),slop搜索下,關鍵詞離的越近,relevance score就會越高。

比如妳搜索壹個java spark,含有java,或者含有是spark,或者同時含有,並且 盡可能讓包含java spark,或者是java和spark離的很近的doc,排在最前面,同時提供了召回率還兼顧了精準率。

直接用match_phrase短語搜索,會導致必須有term都在doc field中出現,而且距離在slop限定範圍內,才能匹配上

此時可以用bool組合match query和match_phrase query壹起,來實現上述效果

match --> 只要簡單的匹配到了壹個term,就可以理解將term對應的doc作為結果返回,掃描倒排索引,掃描到了就ok

phrase match --> 首先掃描到所有term的doc list; 找到包含所有term的doc list; 然後對每個doc都計算每個term的position,是否符合指定的範圍; slop,需要進行復雜的運算,來判斷能否通過slop移動,匹配壹個doc

match query的性能比phrase match和proximity match(有slop)要高很多。因為後兩者都要計算position的距離。

match query比phrase match的性能要高10倍,比proximity match的性能要高20倍。

默認情況下,match也許匹配了1000個doc,proximity match全都需要對每個doc進行壹遍運算,判斷能否slop移動匹配上,然後去貢獻自己的分數

但是很多情況下,match出來也許1000個doc,其實用戶大部分情況下是分頁查詢的,所以可能最多只會看前幾頁,比如壹頁是10條,最多也許就看5頁,就是50條

proximity match只要對前50個doc進行slop移動去匹配,去貢獻自己的分數即可,不需要對全部1000個doc都去進行計算和貢獻分數

match:1000個doc,其實這時候每個doc都有壹個分數了; proximity match,前50個doc,進行rescore,重打分,即可; 讓前50個doc,term舉例越近的,排在越前面

1、前綴搜索

C3D0-KD345

C3K5-DFG65

C4I8-UI365

C3 --> 上面這兩個都搜索出來 --> 根據字符串的前綴去搜索

不用帖子的案例背景,因為比較簡單,直接用自己手動建的新索引,給大家演示壹下就可以了

2、前綴搜索的原理

prefix query不計算relevance score,與prefix filter唯壹的區別就是,filter會cache bitset

掃描整個倒排索引,舉例說明

前綴越短,要處理的doc越多,性能越差,盡可能用長前綴搜索

前綴搜索,它是怎麽執行的?性能為什麽差呢?

match

C3-D0-KD345

C3-K5-DFG65

C4-I8-UI365

全文檢索

每個字符串都需要被分詞

c3 doc1,doc2

d0

kd345

k5

dfg65

c4

i8

ui365

c3 --> 掃描倒排索引 --> 壹旦掃描到c3,就可以停了,因為帶c3的就2個doc,已經找到了 --> 沒有必要繼續去搜索其他的term了

match性能往往是很高的

如果前綴搜索那麽 (前綴搜索是不分詞的)

C3-D0-KD345

C3-K5-DFG65

C4-I8-UI365

c3 --> 先掃描到了C3-D0-KD345,很棒,找到了壹個前綴帶c3的字符串 --> 還是要繼續搜索的,因為後面還有壹個C3-K5-DFG65,也許還有其他很多的前綴帶c3的字符串 --> 妳掃描到了壹個前綴匹配的term,

不能停,必須繼續搜索 --> 直到掃描完整個的倒排索引,才能結束,所以prefix性能很差

3、通配符搜索

跟前綴搜索類似,功能更加強大

C3D0-KD345

C3K5-DFG65

C4I8-UI365

5字符-D任意個字符5

5?-*5:通配符去表達更加復雜的模糊搜索的語義

?:任意字符

*:0個或任意多個字符

性能壹樣差,必須掃描整個倒排索引,才ok

4、正則搜索

C[0-9].+

[0-9]:指定範圍內的數字

[a-z]:指定範圍內的字母

.:壹個字符

+:前面的正則表達式可以出現壹次或多次

wildcard和regexp,與prefix原理壹致,都會掃描整個索引,性能很差

輸入 hello w ,會聯想到hello world,hello we,hello win,hello wind 等等

原理跟match_phrase類似,唯壹的區別,就是把最後壹個term作為前綴去搜索。

hello就是去進行match,搜索對應的doc

w,會作為前綴,去掃描整個倒排索引,找到所有w開頭的doc

然後找到所有doc中,即包含hello,又包含w開頭的字符的doc

根據妳的slop去計算,看在slop範圍內,能不能讓hello w,正好跟doc中的hello和w開頭的單詞的position相匹配

也可以指定slop,但是只有最後壹個term會作為前綴

max_expansions:指定prefix最多匹配多少個term,超過這個數量就不繼續匹配了,限定性能

默認情況下,前綴要掃描所有的倒排索引中的term,去查找w打頭的單詞,但是這樣性能太差。可以用max_expansions限定,w前綴最多匹配多少個term,就不再繼續搜索倒排索引了。

盡量不要用,因為,最後壹個前綴始終要去掃描大量的索引,性能可能會很差,可以使用ngram來實現

什麽是ngram

quick,5種長度下的ngram

ngram length=1,q u i c k

ngram length=2,qu ui ic ck

ngram length=3,qui uic ick

ngram length=4,quic uick

ngram length=5,quick

什麽是edge ngram

quick,首字母後進行ngram

q

qu

qui

quic

quick

-----------------------------------搜索推薦 未完。。。。。。。。。

  • 上一篇:坐點結構部首是什麽
  • 下一篇:打開頁面錯誤 錯誤代碼:403
  • copyright 2024編程學習大全網