一 序
本文屬於極客時間Elasticsearch核心技術與實戰學習筆記系列。
二 單字符串多字段查詢: Multi Match
2.1 三種場景
最佳字段(Best Fields)
- 當字段之間相互競爭,又相互關聯。例如 title 和 body 這樣的字段,評分來自最匹配字段
多數字段(Most Fields)
- 處理英文內容時:一種常見的手段是,在主字段(English Analyzer),抽取詞幹,加入同義詞,以匹配更多的文檔。相同的文本,加入子字段(Standard Analyzer),以提供更加精確的匹配。其他字段作爲匹配文檔提高性相關度的信號。匹配字段越多越好
混合字段(Cross Field)
- 對於某些實體,例如人名,地址,圖書信息。需要在多個字段中確定信息,單個字段只能作爲整體的一部分。希望在任何這些列出的字段中儘可能找出多的詞
Multi Match Query
- Best Fields 是默認類型,可不指定
- Minimum should match 等參數可以傳遞到生成的 query 中
上面的這個例子:外面multi_match 聲明類型,有個query語句,同時指定匹配到哪些查詢字段上。而且這個type是best_fields,就是意味着這些查詢會在這些字段中取一個分數最高的作爲返回結果,同時tie_breaker也是可以指定。
查詢demo
創建一個索引:
PUT /titles
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "english"
}
}
}
}
type指定爲text字段,採用英語分詞器分詞。
POST titles/_bulk
{ "index": { "_id": 1 }}
{ "title": "My dog barks" }
{ "index": { "_id": 2 }}
{ "title": "I see a lot of barking dogs on the road " }
插入數據
從返回的結果來看,不是我們想要的順序,爲什麼呢?
因爲採用了英語分詞器,會把查詢語句拆分成bark dog這個兩個單詞,而這兩個單詞出現的頻率再文檔1,2是一樣的,但是文檔1 更短所以就排到前面。
怎麼設定maping來優化呢?
DELETE /titles
PUT /titles
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "english",
"fields": {"std": {"type": "text","analyzer": "standard"}}
}
}
}
}
對於mapping增加fileds:這裏的standard analyzer,standard analyzer它不會對詞幹做任何的提取,這樣就不會損失查詢的信息。
重建索引之後,需要重新導入數據,這裏我們在執行查詢,默認是best_fields,我們指定爲most_fields,可以吧 "title", "title.std"算分做疊加。
這樣就可以吧最匹配的結果顯示在第一位了。
2.3 跨字段搜索
- most_fields 無法使用 opeartor
- 可以用 copy_to 解決,但是需要額外的儲存空間
- cross_fields 可以支持 operator
- 與 copy_to 相比,其中一個優勢就是可以在搜索時爲某個字段提升權重
demo:
插入數據
PUT address/_doc/1
{
"street":"5 Poland Street",
"city" : "Lodon",
"country":"United Kingdom",
"postcode" : "W1V 3DG"
}
使用most_feilds查詢未空 :因爲例子中的查詢條件是分佈到不同字段上的,而且算分是出現在不同字段上的,沒有很好的算分。
改爲cross_filed:就能查到
小結:
通過Multi Match可以更好的實現單字符串多字段查詢。
學到這裏,我發現es真的比MySQL複雜的多。起碼就查詢sql來看。