1. 程式人生 > >ElasticSearch跨域查詢(多詞搜尋)

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採用的以欄位為中心

(Field-centric)的方法有很大的區別。它將所有的欄位視為一個大的欄位,然後在任一欄位中搜

索每個詞條。

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引數來減少低相關度結果帶來的長尾效應。

三:每個欄位的詞條頻度是不同的,會互相干擾最終得到較差的排序結果。