ElasticSearch跨域查詢(多詞搜尋)
怎麼控制elasticsearch的搜尋的文字匹配精度??
普通的多欄位查詢,可以直接用boolean查詢(如果是boolean查詢的話,那麼有n個查詢條件,最終score=score*1/n),現在讓我們看看一個另外常見的模式:多詞跨欄位搜
索。分散到多個欄位中。如下:
{
"title": "上海廣場",
"content": "北京地址",
"id": "9104240"
}
假設匹配關係為 AND關係。設定查詢關鍵字為北京上海;分為“北京”,“上海”兩個詞。title中含有上海、content含有北京。關鍵字分別命中兩個域。如何搜尋到該文
檔??
一:_all和配置mapping 的copy_to
把多個欄位合併成一個大的欄位。在元資料:_all欄位中,我們解釋了特殊的_all欄位會將其它所有欄位中的值作為一個大字串進行索引。儘管將所有欄位的值作為一個欄位
進行索引並不是非常靈活。如果有一個自定義的_all欄位用來索引人名,另外一個自定義的_all欄位用來索引地址就更好了。
ElasticSearch通過欄位mapping中的copy_to引數向我們提供了這一功能。
現在titile和content欄位中的值會被拷貝到full_name欄位中。
有了這個對映,我們可以跨域,full_name會從title和content中拷貝值。然後根據full_name自身的欄位type,進行分詞。
二:使用multi_match型別為cross_fields的查詢
elasticsearch 的multi_match查詢和match一樣,不同的是它不是針對單個欄位,而是可以通過fields引數針對多個欄位查詢。當然match查詢中可以使用的所有引數同樣可以
在multi_match查詢中使用。
multi_match支援3種查詢型別,best_fields、most_fields、cross_fields。使用型別為cross_fields的multi_match查詢。cross_fields型別採用了一種以詞條為中心(Term-
centric)的方法,這種方法和best_fields及most_fields採用的以欄位為中心
索每個詞條。
operator:operator設為了and,表示所有的詞條都需要出現;
minimum_should_match:表示文字匹配度,控制搜尋精度,向下取整。
1:我們會希望這個詞條的分詞詞彙是分配到不同欄位中的,那麼就使用cross_fields
{
"query": {
"multi_match": {
"query": "北京上海",
"type": "cross_fields",
"fields": [
"title",
"content"
]
}
}
}
java實現:
builder.should(QueryBuilders.multiMatchQuery(keyword, "title.ik^1.5", "storeAddress.ik","plazaName.ik","countyName.ik").type(Type.CROSS_FIELDS).minimumShouldMatch("67%"));
2:我們希望完全匹配的文件佔的評分比較高,則需要使用best_fields
預設情況下,該查詢以best_fields型別執行,它會為每個欄位生成一個match查詢,然後將這些查詢包含在一個dis_max查詢中。下面的dis_max查詢:{
"query": {
"multi_match": {
"query": "北京上海",
"type": "best_fields",
"fields": [
"title",
"content"
],
"tie_breaker": 0.3
}
}
}
意思就是完全匹配"北京上海"的文件評分會比較靠前,如果只匹配寶馬的文件評分乘以0.3的係數
3:我們希望越多欄位匹配的文件評分越高,就要使用most_fields
{
"query": {
"multi_match": {
"query": "北京上海",
"type": "most_fields",
"fields": [
"title",
"content"
]
}
}
}
使用most_fields方法執行實體查詢有一些不那麼明顯的問題:
一:它被設計用來找到匹配任意單詞的多數字段,而不是找到跨越所有欄位的最匹配的單詞。
二:它不能使用operator或者minimum_should_match引數來減少低相關度結果帶來的長尾效應。
三:每個欄位的詞條頻度是不同的,會互相干擾最終得到較差的排序結果。