2014-01-16 50 views
6

在我的Elasticsearch索引中,我有在同一位置有多個標記的文檔。Elasticsearch:僅匹配每個位置一次

我想在每個位置匹配至少一個令牌時返回文檔。 令牌的順序並不重要。 我該怎麼做到這一點?我使用Elasticsearch 0.90.5。

實施例:

I指數這樣的文檔。

{ 
    "field":"red car" 
} 

我使用同義詞標記過濾器,在與原始標記相同的位置添加同義詞。 所以現在在外地,有2位:

  • 職位1: 「紅」
  • 位置2: 「汽車」, 「汽車」

我現在的解決方案:

爲了能夠確保所有職位相匹配,我也編制了最大職位。

{ 
    "field":"red car", 
    "max_position": 2 
} 

我有一個自定義的相似性,從DefaultSimilarity延伸並返回1 tf(),idf()和lengthNorm()。得到的分數是該字段中匹配項的數量。

查詢:

{ 
    "custom_score": { 
     "query": { 
      "match": { 
       "field": "a car is an automobile" 
      } 
     }, 
     "_script": "_score*100/doc[\"max_position\"]+_score" 
    }, 
    "min_score":"100" 
} 

問題,我的解決方案:

上面搜索應該無法比擬的文件,因爲沒有標記「紅色」的查詢字符串。但它匹配,因爲Elasticsearch將賽車和汽車的比賽計爲兩場比賽,並且得分爲2,這導致腳本得分爲102,滿足「min_score」。

回答

0

如果您需要保證與查詢條件的100%匹配,您可以使用minimum_should_match。這是比較常見的情況。


不幸的是,你的情況,你要提供索引項的100%匹配。爲此,您必須下降到Lucene級別並編寫自定義類(java - here's boilerplate you can fork)相似度類,因爲您需要訪問不接觸查詢DSL的低級索引信息:

每在查詢射手掃描的文檔/字段:

然後你自定義的相似性(你可能甚至擴展DefaultSimilarity)將需要檢測,其中方面匹配 < 總條款查詢,並通過零增加他們的分數。

由於查詢和索引時間分析已經發生在這一級別的評分中,索引術語的總數已經擴展到包括同義詞,查詢術語也應該如此,避免誤報「一輛車是汽車「以上問題。