[英]Elasticsearch: Search over most frequent matches / terms without TF or IDF adjustment
我們正在研究基於文本的搜索(通過著名的“在此處鍵入您的搜索”輸入框),它計算多個字段的分數並顯示最佳結果。 它基本上是一個布爾查詢,在許多不同的字段上混合了“術語”和“匹配”(使用模糊度、ngram、edge-ngrams 等)。
我們希望最好的結果(最“受歡迎”)首先出現(從而獲得最高分)。 然而,lucene 的默認 TF-IDF 算法給了我們完全相反的結果。 圖像您尋找存在於 30% 的所有索引條目中的供應商。 它將具有非常高的 IDF 並且排名非常低。 我們只想要完全相反的 - 給我們最頻繁的第一個(!)。
嘗試使用“cross-field”查詢並沒有成功,因為我們想將不同的查詢類型與“bool”結合起來。
現在,我們“發現”的是,使用 k1=0 和 b=0 幾乎(?)的 Okapi BM25 的行為就像忽略了 TF(詞頻)和 IDF(逆文檔頻率)的相似性。 然而,我們不確定這是否真的是要走的路。
你能給我們一些反饋嗎?
這是要走的路還是對於我們的“問題”是否有更好的等待被發現?
我試着讓我的問題更清楚(對不起,任何混淆):
假設我們有一個汽車索引......
{id: 1, vendor: Opel, model: Astra, engine: 90hp gasoline}
{id: 2, vendor: Opel, model: Astra, engine: 100hp diesel}
{id: 3, vendor: Opel, model: Astra, engine: 120hp gasoline}
{id: 4, vendor: Chevrolet, model: Astro, engine: 120hp gasoline}
我們對當前用戶輸入的“astr”進行“全文搜索”
使用“edge ngram”分析器 {min:2, max:10} 分析所有字段(供應商、模型 + 引擎)以支持前綴搜索。
輸入“astr”將匹配所有條目 #1 - #4(它是“Astra”和“Astro”的開頭,所以所有條目都將包含一個邊 ngram 匹配)
“Astr a ”的 IDF 是 log(4/3) ~= 0,287
“Astr o ”的 IDF 是 log(4/1) ~= 1,386
因此,由於 IDF,#4 的排名會更好
然而,我們想要恰恰相反:“更頻繁”(=“更受歡迎”)的汽車應該排名更高。
注意:“跨字段”查詢是不夠的,因為我們將幾個不同的查詢(模糊、邊緣 ngram、原始)合並到一個大的 bool 查詢中
聽起來您想遵循以下一般流程:
解決方案 1 (最靈活,性能最低)
您可以使用供應商字段上的術語聚合來獲取 #2 的信息。
然后您可以使用必要的派生提升重新查詢(花費第二次往返)
或者
解決方案 2 (最不靈活,性能最高)
如果您滿足於讓vendor popularity
勝過_score
,您可以執行以下操作:
那么聚合結果中的[astr]
查詢結果將如下所示:
[Opel bucket]
Astra 90hp
Astra 100hp diesel
Astra 120hp
Ascona 144hp (if you had fuzziness 2)
Ascona 230hp (if you had fuzziness 2)
[Chevrolet bucket]
Astro 120hp
Alero 140hp (if you had fuzziness 2)
如果您想使用文檔頻率來提高結果,請嘗試在function_score
子句中滾動您自己的script_score函數。 您可以通過term statistics訪問評分函數中某個術語的文檔頻率。
您可能會發現這種方法的一個意想不到的后果是,如果您沒有明確地將它們作為停用詞清除掉,諸如Corp
、 Solutions
、 Computer
、 Inc
等常見/通用術語將對您的分數產生巨大影響。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.