二十二、elasticSearch的most-fields策略

1、most-fields策略
best-fields策略,主要是說將某一個field匹配盡可能多的關鍵詞的doc優先返回回來
most-fields策略,主要是說盡可能返回更多field匹配到某個關鍵詞的doc,優先返回回來,用法和上面的一樣
當我們相查找與learning courses相關的數據時如果數據如下:
{ "update": { "_id": "1"} }
{ "doc" : {"sub_title" : "learning more courses"} }
{ "update": { "_id": "2"} }
{ "doc" : {"sub_title" : "learned a lot of course"} }

GET /forum/article/_search
{
"query": {
"match": {
"sub_title": "learning courses"
}
}
}
查出來可以_id為2的在前面,因為如果我們用的是類似于english analyzer這種分詞器的話,就會將單詞還原為其最基本的形態,類似:
learning --> learn
learned --> learn
courses --> course
使用下面做
GET /forum/article/_search
{
"query": {
"multi_match": {
"query": "learning courses",
"type": "best_fields",
"fields": [ "sub_title.std" ]
}
}
}

2、most-fields與best_fields的區別
(1)best_fields,是對多個field進行搜索,挑選某個field匹配度最高的那個分數,同時在多個query最高分相同的情況下,在一定程度上考慮其他query的分數。簡單來說,你對多個field進行搜索,就想搜索到某一個field盡可能包含更多關鍵字的數據

優點:通過best_fields策略,以及綜合考慮其他field,還有minimum_should_match支持,可以盡可能精準地將匹配的結果推送到最前面
缺點:除了那些精準匹配的結果,其他差不多大的結果,排序結果不是太均勻,沒有什么區分度了

實際的例子:百度之類的搜索引擎,最匹配的到最前面,但是其他的就沒什么區分度了

(2)most_fields,綜合多個field一起進行搜索,盡可能多地讓所有field的query參與到總分數的計算中來,此時就會是個大雜燴,某一個document的一個field包含更多的關鍵字,但是因為其他document有更多field匹配到了,所以排在了前面;所以需要建立類似sub_title.std這樣的field,盡可能讓某一個field精準匹配query string,貢獻更高的分數,將更精準匹配的數據排到前面

優點:將盡可能匹配更多field的結果推送到最前面,整個排序結果是比較均勻的
缺點:可能那些精準匹配的結果,無法推送到最前面
3、cross-fields搜索
cross-fields搜索,一個唯一標識,跨了多個field。比如一個人,標識,是姓名;一個建筑,它的標識是地址。姓名可以散落在多個field中,比如first_name和last_name中,地址可以散落在country,province,city中。

初步來說,如果要實現,可能用most_fields比較合適。因為best_fields是優先搜索單個field最匹配的結果,cross-fields本身就不是一個field的問題了。

POST /forum/article/_bulk
{ "update": { "_id": "1"} }
{ "doc" : {"author_first_name" : "Peter", "author_last_name" : "Smith"} }
{ "update": { "_id": "2"} }
{ "doc" : {"author_first_name" : "Smith", "author_last_name" : "Williams"} }
{ "update": { "_id": "3"} }
{ "doc" : {"author_first_name" : "Jack", "author_last_name" : "Ma"} }
{ "update": { "_id": "4"} }
{ "doc" : {"author_first_name" : "Robbin", "author_last_name" : "Li"} }
{ "update": { "_id": "5"} }
{ "doc" : {"author_first_name" : "Tonny", "author_last_name" : "Peter Smith"} }

GET /forum/article/_search
{
"query": {
"multi_match": {
"query": "Peter Smith",
"type": "cross_fields",
"operator":"and",
"fields": ["author_first_name", "author_last_name"]
}
}
}
問題1:只是找到盡可能多的field匹配的doc,而不是某個field完全匹配的doc --> 解決,要求每個term都必須在任何一個field中出現
Peter,Smith
要求Peter必須在author_first_name或author_last_name中出現
要求Smith必須在author_first_name或author_last_name中出現
Peter Smith可能是橫跨在多個field中的,所以必須要求每個term都在某個field中出現,組合起來才能組成我們想要的標識,完整的人名
原來most_fiels,可能像Smith Williams也可能會出現,因為most_fields要求只是任何一個field匹配了就可以,匹配的field越多,分數越高

問題2:TF/IDF算法,比如Peter Smith和Smith Williams,搜索Peter Smith的時候,由于first_name中很少有Smith的,所以query在所有document中的頻率很低,得到的分數很高,可能Smith Williams反而會排在Peter Smith前面 --> 計算IDF的時候,將每個query在每個field中的IDF都取出來,取最小值,就不會出現極端情況下的極大值了
4、copy_to用法
就是合并多個field 將多個字段的值拷貝到一個字段中,并建立倒排索引
PUT /forum/_mapping/article
{
"properties": {
"new_author_first_name": {
"type": "string",
"copy_to": "new_author_full_name"
},
"new_author_last_name": {
"type": "string",
"copy_to": "new_author_full_name"
},
"new_author_full_name": {
"type": "string"
}
}
}

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容