1. 程式人生 > >elasticsearch(14) best_field策略和most_field策略

elasticsearch(14) best_field策略和most_field策略

從best-fields換成most-fields策略 best-fields策略,主要是說將某一個field匹配儘可能多的關鍵詞的doc優先返回回來 most-fields策略,主要是說盡可能返回更多field匹配到某個關鍵詞的doc,優先返回回來

POST /forum/_mapping/article {   "properties": {       "sub_title": {            "type":     "string",           "analyzer": "english",           "fields": {               "std":   {                    "type":     "string",                   "analyzer": "standard"               }           }       }   } }

POST /forum/article/_bulk { "update": { "_id": "1"} } { "doc" : {"sub_title" : "learning more courses"} } { "update": { "_id": "2"} } { "doc" : {"sub_title" : "learned a lot of course"} } { "update": { "_id": "3"} } { "doc" : {"sub_title" : "we have a lot of fun"} } { "update": { "_id": "4"} } { "doc" : {"sub_title" : "both of them are good"} } { "update": { "_id": "5"} } { "doc" : {"sub_title" : "haha, hello world"} }

GET /forum/article/_search {   "query": {     "match": {       "sub_title": "learning courses"     }   } }

{   "took": 3,   "timed_out": false,   "_shards": {     "total": 5,     "successful": 5,     "failed": 0   },   "hits": {     "total": 2,     "max_score": 1.219939,     "hits": [       {         "_index": "forum",         "_type": "article",         "_id": "2",         "_score": 1.219939,         "_source": {           "articleID": "KDKE-B-9947-#kL5",           "userID": 1,           "hidden": false,           "postDate": "2017-01-02",           "tag": [             "java"           ],           "tag_cnt": 1,           "view_cnt": 50,           "title": "this is java blog",           "content": "i think java is the best programming language",           "sub_title": "learned a lot of course"         }       },       {         "_index": "forum",         "_type": "article",         "_id": "1",         "_score": 0.5063205,         "_source": {           "articleID": "XHDK-A-1293-#fJ3",           "userID": 1,           "hidden": false,           "postDate": "2017-01-01",           "tag": [             "java",             "hadoop"           ],           "tag_cnt": 2,           "view_cnt": 30,           "title": "this is java and elasticsearch blog",           "content": "i like to write best elasticsearch article",           "sub_title": "learning more courses"         }       }     ]   } }

sub_title用的是enligsh analyzer,所以還原了單詞

為什麼,因為如果我們用的是類似於english analyzer這種分詞器的話,就會將單詞還原為其最基本的形態,stemmer learning --> learn learned --> learn courses --> course

sub_titile: learning coureses --> learn course

{ "doc" : {"sub_title" : "learned a lot of course"} },就排在了{ "doc" : {"sub_title" : "learning more courses"} }的前面

GET /forum/article/_search {    "query": {         "match": {             "sub_title": "learning courses"         }     } }

很繞。。。。我自己都覺得很繞

很多東西,你看文字就覺得很繞,然後用語言去表述,也很繞,但是我覺得,用語言去說,相對來說會好一點點

GET /forum/article/_search {    "query": {         "multi_match": {             "query":  "learning courses",             "type":   "most_fields",              "fields": [ "sub_title", "sub_title.std" ]         }     } }

{   "took": 2,   "timed_out": false,   "_shards": {     "total": 5,     "successful": 5,     "failed": 0   },   "hits": {     "total": 2,     "max_score": 1.219939,     "hits": [       {         "_index": "forum",         "_type": "article",         "_id": "2",         "_score": 1.219939,         "_source": {           "articleID": "KDKE-B-9947-#kL5",           "userID": 1,           "hidden": false,           "postDate": "2017-01-02",           "tag": [             "java"           ],           "tag_cnt": 1,           "view_cnt": 50,           "title": "this is java blog",           "content": "i think java is the best programming language",           "sub_title": "learned a lot of course"         }       },       {         "_index": "forum",         "_type": "article",         "_id": "1",         "_score": 1.012641,         "_source": {           "articleID": "XHDK-A-1293-#fJ3",           "userID": 1,           "hidden": false,           "postDate": "2017-01-01",           "tag": [             "java",             "hadoop"           ],           "tag_cnt": 2,           "view_cnt": 30,           "title": "this is java and elasticsearch blog",           "content": "i like to write best elasticsearch article",           "sub_title": "learning more courses"         }       }     ]   } }

你問我,具體的分數怎麼算出來的,很難說,因為這個東西很複雜, 還不只是TF/IDF演算法。因為不同的query,不同的語法,都有不同的計算score的細節。

與best_fields的區別

(1)best_fields,是對多個field進行搜尋,挑選某個field匹配度最高的那個分數,同時在多個query最高分相同的情況下,在一定程度上考慮其他query的分數。簡單來說,你對多個field進行搜尋,就想搜尋到某一個field儘可能包含更多關鍵字的資料

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

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

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

優點:將盡可能匹配更多field的結果推送到最前面,整個排序結果是比較均勻的 缺點:可能那些精準匹配的結果,無法推送到最前面

實際的例子:wiki,明顯的most_fields策略,搜尋結果比較均勻,但是的確要翻好幾頁才能找到最匹配的結果