2017-08-07 141 views
0

我有這樣的查詢(我已經移除的分揀部分,因爲它並不重要)一起multi_match:Elasticsearch - 短查詢

GET _search 
{ 
    "query": { 
    "multi_match": { 
     "query": "somethi", 
     "fields": [ "title", "content"], 
     "fuzziness" : "AUTO", 
     "prefix_length" : 0 
    } 
    } 
} 

運行此我得到的結果是這樣的:

"hits": [ 
    { 
    "_index": "test_index", 
    "_type": "article", 
    "_id": "2", 
    "_score": 0.083934024, 
    "_source": { 
     "title": "Matching something abc", 
     "content": "This is a piece of content", 
     "categories": [ 
     { 
      "name": "B", 
      "weight": 4 
     } 
     ] 
    }, 
    "sort": [ 
     4, 
     0.083934024, 
     "article#2" 
    ] 
    }, 
    { 
    "_index": "test_index", 
    "_type": "article", 
    "_id": "3", 
    "_score": 0.18436861, 
    "_source": { 
     "title": "Matching something abc", 
     "content": "This is a piece of content containing something", 
     "categories": [ 
     { 
      "name": "C", 
      "weight": 3 
     } 
     ] 
    }, 
    "sort": [ 
     3, 
     0.18436861, 
     "article#3" 
    ] 
    }, 
    ... 

所以沒有問題得到什麼預期。但是我注意到,我從查詢中刪除一個字母代替someth,Elasticsearch不會返回任何結果。

這對我來說很奇怪。看來multi_match正在做部分匹配,但它以某種方式需要使用最少的x個字符。相同,如果我試圖把查詢例如omethin我會得到的結果,但只使用omethi我不會得到任何。

是否有任何設置來設置查詢中的最少字符數或者我可能需要重寫我的查詢來實現我想要的?我想在多個字段(在標題和內容字段的上面的查詢中)上運行匹配,這將允許部分匹配和模糊。

回答

1

您得到此行爲是因爲您有"fuzziness": "AUTO"參數集,這意味着在超過5個字符的單詞中,最多錯誤放置兩個字符是可以接受的。一般來說,fuzziness parameter告訴elasticsearch最多查找兩個更改,其中更改是單個字符的插入,刪除或替換。隨着模糊性,不可能有兩個以上的變化。

如果您需要使用部分匹配進行搜索,則可以嘗試使用Edge NGram analyzer配置索引,並將其設置爲您的titlecontent字段。您可以輕鬆地測試它是如何工作的:

創建娜與以下映射索引:

PUT http://127.0.0.1:9200/test 
{ 
    "settings": { 
    "analysis": { 
     "analyzer": { 
     "edge_ngram_analyzer": { 
      "tokenizer": "my_tokenizer" 
     } 
     }, 
     "tokenizer": { 
     "my_tokenizer": { 
      "type": "edge_ngram", 
      "min_gram": 2, 
      "max_gram": 10, 
      "token_chars": [ 
      "letter", 
      "digit" 
      ] 
     } 
     } 
    } 
    } 
} 

並運行此查詢:

curl -X POST \ 
    'http://127.0.0.1:9200/test/_analyze?pretty=true' \ 
    -d '{ 
    "analyzer" : "edge_ngram_analyzer", 
    "text" : ["something"] 
}' 

因此,您將獲得:

{ 
    "tokens": [ 
     { 
      "token": "so", 
      ... 
     }, 
     { 
      "token": "som", 
      ... 
     }, 
     { 
      "token": "some", 
      ... 
     }, 
     { 
      "token": "somet", 
      ... 
     }, 
     { 
      "token": "someth", 
      ... 
     }, 
     { 
      "token": "somethi", 
      ... 
     }, 
     { 
      "token": "somethin", 
      ... 
     }, 
     { 
      "token": "something", 
      ... 
     } 
    ] 
} 

這些是您在使用edge_ngram_analyzer進行搜索時會得到的令牌。使用min_grammax_gram,您可以配置一個gram中的最小/最大字符長度。

如果您需要使用omething等(在開始處丟失字母)處理此案,請嘗試使用NGram analyzer

+0

謝謝。我今天和NGRAM的分析師一起玩,看起來它是做這個工作的。我與fuzinness一起使用沒有更大的問題 –