search(10)- elastic4s-multi_match:多字段全文搜索

   在全文搜索中咱們經常會在多個字段中匹配同一個查詢條件或者在不一樣的字段中匹配不一樣的條件。好比下面這個例子:網站

GET /books/_search { "query": { "bool": { "should": [ { "match": { "title":  "和平戰爭" }}, { "match": { "author": "託斯泰" }} ] } } }

咱們能夠用boolQuery來進行查詢語句的組合。全文搜索會產生匹配度評分。boolQuery採起的評分策略是:符合條件的語句越多,評分就越高。若是查詢結果按評分倒排序的話,那麼排在最前面的就是最有可能的結果了。boolQuery能夠包含boolQuery,以下:spa

GET /books/_search { "query": { "bool": { "should": [ { "match": { "title":  "和平戰爭" }}, { "match": { "author": "託斯泰" }}, "bool" : { "should" : [ {"match" : { "translator" : ""}}, {"match" : { "translator" : ""}} ] } ] } } }

增長條件的意思是:若是翻譯者姓陳或姓王,那麼評分就高點。不過把boolQuery嵌入另外一個boolQuery會影響外部boolQuery的評分結果。由於嵌入的boolQuery只佔總評分的三分之一。固然能夠經過boost來平衡比重,以下:翻譯

GET /books/_search { "query": { "bool": { "should": [ { "match": { "title": { "query": "和平戰爭", "boost": 2 } } }, { "match": { "author": "託斯泰" }}, "bool" : { "should" : [ {"match" : { "translator" : ""}}, {"match" : { "translator" : ""}} ] } ] } } }

從上面的例子裏能夠看到:boolQuery是典型的多字段多條件匹配查詢,用戶必須明確分辨那些條件在那些字段裏匹配。但人們習慣於一句話裏表達多個字段的條件。或者他們根本不想分辨任何字段,指望一句話就獲得想要的結果。這個時候boolQuery就不太適合使用了。code

首先,咱們能夠嘗試在多個字段中匹配一樣一個綜合語句如:和平戰爭託斯泰。這時咱們可能面臨3種選擇:blog

一、best-fields:一樣一個條件在不一樣的字段裏匹配產生多個評分,總體查詢只取最優評分排序

二、most-fields: 這個方法有點複雜,須要在建索引時把一個字段按分詞方式分紅多個字段,查詢時取知足條件最多字段的評分索引

三、cross-fields:把全部涉及的字段合成一個大字段,而後用條件來匹配這個組合而成的字段。這個方法應該最適合咱們的要求it

咱們先分析一下具體場景:一我的想在網站上找一本書,應該會從書名、做者、出版社這幾個方面提供查詢條件(雖然是在一個輸入框輸入條件),也就是說用戶提供的一個查詢條件裏可能包含了書名、做者、出版社這幾方面的信息。那麼第一個版本的搜索請求以下:ast

GET /books/_search { "query": { "multi_match": { "query": "和平與戰爭 託斯泰 人民出版社", "type": "cross_fields", "fields": ["title","author","publisher"] } } }

按理來說書名的比重應該高於做者,出版社,因此應該爲title加比重:class

GET /books/_search { "query": { "multi_match": { "query": "和平與戰爭 託斯泰 人民出版社", "type": "cross_fields", "fields": ["title^2","author","publisher"] } } }

爲了更精確的篩選,詞句terms應該採起and進行關聯:

GET /books/_search { "query": { "multi_match": { "query": "和平與戰爭 託斯泰 人民出版社", "type": "cross_fields", "fields": ["title","author","publisher"], "operator": "and" } } }

得出的結果集會大大縮短。用戶能夠取消一些條件來增長結果範圍。作的再仔細點咱們還能夠在圖書的內容上面作點功夫:

GET /books/_search { "query": { "multi_match": { "query": "和平與戰爭 託斯泰 人民出版社", "type": "cross_fields", "fields": ["title^3","author^2","publisher^2","toc","intro"], "operator": "and" } } }

增長了目錄toc, 內容簡介intro。不過它們的比重是最低的。

elastic4示例以下:

 val qMultiMatch = search("books").query( multiMatchQuery("和平與戰爭 託斯泰 人民出版社") .matchType("cross_fields") .operator("and") .fields( "title^3", "author^2", "publisher^2", "toc", "intro" ) ).sourceInclude("ISBN","title","publisher","price","author")
相關文章
相關標籤/搜索