Elasticsearch 單字符串多字段查詢

前言

有些時(shí)候,我們搜索的時(shí)候,只會(huì)提供一個(gè)輸入框,但是會(huì)查詢相關(guān)的多個(gè)字段,典型的如Google搜索,我們?cè)撊绾斡?Elasticsearch 如何實(shí)現(xiàn)呢?

實(shí)例

從單字符串查詢的實(shí)例說起

創(chuàng)建測(cè)試?yán)拥臄?shù)據(jù)

DELETE blogs

PUT blogs/_doc/_bulk
{"index":{"_id":1}}
{"title": "Quick brown rabbits","body": "Brown rabbits are commonly seen."}
{"index":{"_id":2}}
{"title": "Keeping pets healthy","body": "My quick brown fox eats rabbits on a regular basis"}
GET blogs/_search
{
  "explain": true,
  "query": {
    "bool": {
      "should": [
        {"match": {"title": "Brown fox"}},
        {"match": {"body": "Brown fox"}}
      ]
    }
  }
}

上面的例子相關(guān)性的值是title與body的簡(jiǎn)單相加,可以通過“"explain": true”打印出來的數(shù)據(jù)進(jìn)行查詢計(jì)算的過程。

最優(yōu)字段查詢調(diào)優(yōu)

可以使用disjunction max query,讓其匹配最大相關(guān)性那個(gè)字段,同時(shí)tie_breaker可以調(diào)整相關(guān)性,取值范圍是0~1,可以控制相關(guān)性較小那個(gè)值占用的比例,默認(rèn)是0,畢竟只要相關(guān)性最大那個(gè)字段就好了,其他字段不打分。

GET blogs/_search
{
  "explain": true,
  "query": {
    "dis_max": {
      "queries": [
        {"match": {"title": "Brown fox"}},
        {"match": {"body": "Brown fox"}}
      ],
      "tie_breaker": 0.7
    }
  }
}

相關(guān)性的值是title與body中的最大值。

multi_match

multi_match 查詢?yōu)槟茉诙鄠€(gè)字段上反復(fù)執(zhí)行相同查詢提供了一種便捷方式。

上面的dis_max例子改寫如下

GET blogs/_search
{
  "explain": true, 
  "query": {
    "multi_match": {
      "type": "most_fields", 
      "query": "Brown fox",
      "fields": ["title","body"],
      "tie_breaker": 0.7
    }
  }
}

multi_match 查詢

multi_match 支持三種場(chǎng)景

  • best_fields——(默認(rèn))查找匹配任何字段的文檔,但是使用最佳匹配字段的_score。
  • most_fields——查找匹配任何字段的文檔,結(jié)合每個(gè)字段的_score。
  • cross_fields——用相同的分析器處理字段,把這些字段當(dāng)作一個(gè)大字段。查找任何字段的每個(gè)單詞。類似copy_to

query中可以指定minimum_should_match、operator等字段,會(huì)把這些字段傳遞到query語句中

best_fields

當(dāng)搜索詞語具體概念的時(shí)候,比如 “brown fox” ,詞組比各自獨(dú)立的單詞更有意義。像 title 和 body 這樣的字段,盡管它們之間是相關(guān)的,但同時(shí)又彼此相互競(jìng)爭(zhēng)。文檔在相同字段 中包含的詞越多越好,評(píng)分也來自于最匹配字段 。

best_fields 語句 等同于 dis_max 語句,可以配置tie_breaker參數(shù)。

most_fields

全文搜索被稱作是 召回率(Recall) 與 精確率(Precision) 的戰(zhàn)場(chǎng): 召回率 ——返回所有的相關(guān)文檔; 精確率 ——不返回?zé)o關(guān)文檔。目的是在結(jié)果的第一頁(yè)中為用戶呈現(xiàn)最為相關(guān)的文檔。

為了提高召回率的效果,我們擴(kuò)大搜索范圍——不僅返回與用戶搜索詞精確匹配的文檔,還會(huì)返回我們認(rèn)為與查詢相關(guān)的所有文檔。如果一個(gè)用戶搜索 “quick brown box” ,一個(gè)包含詞語“fast foxes”的文檔被認(rèn)為是非常合理的返回結(jié)果。

提高全文相關(guān)性精度的常用方式是為同一文本建立多種方式的索引,每種方式都提供了一個(gè)不同的相關(guān)度信號(hào)signal。主字段會(huì)以盡可能多的形式的去匹配盡可能多的文檔。

DELETE titles

PUT titles
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "english",
        "fields": {"std": {"type": "text","analyzer": "standard"}}
      }
    }
  }
}
GET /titles/_search
{
  "query": {
    "multi_match": {
      "query":  "barking dogs",
      "type":   "most_fields",
      "fields": [ "title^10", "title.std" ]
    }
  }
}

比如這個(gè)例子,文檔中的“title”被索引了兩次,主字段“title”的分詞器是“english”,會(huì)提取詞干,“a”,“the”等這些會(huì)在分詞過程中被過濾掉,“ing”等會(huì)去除,子字段“title.std”的分詞器是“standard”,不會(huì)提取詞干。

同時(shí)指定了boost,比如上面的“title^10”,表示“title”的權(quán)重是10。

cross_fields

對(duì)于某些實(shí)體,我們需要在多個(gè)字段中確定其信息,單個(gè)字段都只能作為整體的一部分:

Person: first_name 和 last_name (人:名和姓)
Book: title 、 author 和 description (書:標(biāo)題、作者、描述)
Address: street 、 city 、 country 和 postcode (地址:街道、市、國(guó)家和郵政編碼)

在這種情況下,我們希望在任何 這些列出的字段中找到盡可能多的詞,這有如在一個(gè)大字段中進(jìn)行搜索,這個(gè)大字段包括了所有列出的字段。

這個(gè)類似copy_to,copy_to需要額外的存儲(chǔ)空間,這個(gè)不需要。

支持 operator 操作,如果指定的是“and”,那么表示所有詞都是必須的。

參考資料

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容