2012-02-13 87 views
16

如果我在Solr中有一個帶有多值字段的文檔,那麼多個值是獨立得分還是隻是連在一起並且作爲一個大字段打分?我希望他們獨立得分。這裏是我的意思的一個例子:solr多值字段的得分

我有一個字段的人的名字,其中可能有多個同名人的名字的文件。名字都是不同的(在某些情況下有很大的不同),但它們都是同一個人/文檔。

人1: 大衛·鮑伊,大衛·羅伯特·瓊斯,齊吉星塵,薄白公爵

人2: 大衛·萊特曼

人3: 大衛·哈塞爾霍夫,大衛·邁克爾·哈塞爾霍夫

如果我要搜索「大衛」,我希望所有這些人都有相同的比賽機會。如果每個名字獨立得分,看起來就是這樣。如果他們只是作爲一個單獨的領域進行存儲和搜索,David Bowie將因爲擁有更多的令牌而受到懲罰。 Solr如何處理這種情況?

回答

18

你可以運行你的查詢q=field_name:DaviddebugQuery=on看看會發生什麼。

這些結果(包括通過fl=*,score分數)由score desc排序:

<doc> 
    <float name="score">0.4451987</float> 
    <str name="id">2</str> 
    <arr name="text_ws"> 
     <str>David Letterman</str> 
    </arr> 
</doc> 
<doc> 
    <float name="score">0.44072422</float> 
    <str name="id">3</str> 
    <arr name="text_ws"> 
     <str>David Hasselhoff</str> 
     <str>David Michael Hasselhoff</str> 
    </arr> 
</doc> 
<doc> 
    <float name="score">0.314803</float> 
    <str name="id">1</str> 
    <arr name="text_ws"> 
     <str>David Bowie</str> 
     <str>David Robert Jones</str> 
     <str>Ziggy Stardust</str> 
     <str>Thin White Duke</str> 
    </arr> 
</doc> 

而且這樣的解釋:

<lst name="explain"> 
    <str name="2"> 
     0.4451987 = (MATCH) fieldWeight(text_ws:David in 1), product of: 1.0 = tf(termFreq(text_ws:David)=1) 0.71231794 = idf(docFreq=3, maxDocs=3) 0.625 = fieldNorm(field=text_ws, doc=1) 
    </str> 
    <str name="3"> 
     0.44072422 = (MATCH) fieldWeight(text_ws:David in 2), product of: 1.4142135 = tf(termFreq(text_ws:David)=2) 0.71231794 = idf(docFreq=3, maxDocs=3) 0.4375 = fieldNorm(field=text_ws, doc=2) 
    </str> 
    <str name="1"> 
     0.314803 = (MATCH) fieldWeight(text_ws:David in 0), product of: 1.4142135 = tf(termFreq(text_ws:David)=2) 0.71231794 = idf(docFreq=3, maxDocs=3) 0.3125 = fieldNorm(field=text_ws, doc=0) 
    </str> 
</lst> 

的評分這裏的因素是:

  • termFreq:howt連接一個詞出現在文檔中
  • IDF:術語出現的頻率在整個指數
  • fieldNorm:術語的重要性,這取決於指數時間提高和字段長度

在你的例子fieldNorm會有所作爲。由於該字段只出現一次,因此您有一個文檔的更低的termFreq(1而不是1.4142135),但由於字段長度的原因該匹配更重要。

您的字段是多值的事實不會改變評分。我想這與內容相同的單個值域相同。 Solr根據字段長度和術語工作,所以,是的,David Bowie因爲擁有比其他許多令牌而受到懲罰。 :)

UPDATE
其實,我覺得大衛·鮑伊值得他的機會。像上面解釋的那樣,fieldNorm是有差別的。將屬性omitNorms=true添加到您的text_ws字段中的schema.xml和reindex。同樣的查詢會給你以下結果:

<doc> 
    <float name="score">1.0073696</float> 
    <str name="id">1</str> 
    <arr name="text"> 
     <str>David Bowie</str> 
     <str>David Robert Jones</str> 
     <str>Ziggy Stardust</str> 
     <str>Thin White Duke</str> 
    </arr> 
</doc> 
<doc> 
    <float name="score">1.0073696</float> 
    <str name="id">3</str> 
    <arr name="text"> 
     <str>David Hasselhoff</str> 
     <str>David Michael Hasselhoff</str> 
    </arr> 
</doc> 
<doc> 
    <float name="score">0.71231794</float> 
    <str name="id">2</str> 
    <arr name="text"> 
     <str>David Letterman</str> 
    </arr> 
</doc> 

正如你可以看到現在的termFreq勝的fieldNorm沒有考慮到的。這就是爲什麼包含兩次大衛事件的兩份文件儘管長度各不相同,但仍處於頂端並且得分相同,而只有一場比賽的較短文檔是最後一次得分最低的文檔。下面是與debugQuery=on的解釋:

<lst name="explain"> 
    <str name="1"> 
     1.0073696 = (MATCH) fieldWeight(text:David in 0), product of: 1.4142135 = tf(termFreq(text:David)=2) 0.71231794 = idf(docFreq=3, maxDocs=3) 1.0 = fieldNorm(field=text, doc=0) 
    </str> 
    <str name="3"> 
     1.0073696 = (MATCH) fieldWeight(text:David in 2), product of: 1.4142135 = tf(termFreq(text:David)=2) 0.71231794 = idf(docFreq=3, maxDocs=3) 1.0 = fieldNorm(field=text, doc=2) 
    </str> 
    <str name="2"> 
     0.71231794 = (MATCH) fieldWeight(text:David in 1), product of: 1.0 = tf(termFreq(text:David)=1) 0.71231794 = idf(docFreq=3, maxDocs=3) 1.0 = fieldNorm(field=text, doc=1) 
    </str> 
</lst> 
+0

感謝您的詳細分類,這正是我需要知道的。有沒有另外一種方法可以將這些數據編入索引,讓這些名稱的評分更「公平」? – user605331 2012-02-13 15:02:46

+1

@ user605331看看我更新的答案,我也給了David Bowie一個機會! – javanna 2012-02-20 19:03:25

+1

省略規範有所幫助,但這不是一個好的解決方案。有人可能需要考慮fieldNorm,但仍然需要使用多值字段。所以我們必須在這兩個之間做出決定:( – 2014-09-18 08:32:03

3

你可以使用Lucenes SweetSpotSimilarity定義的長度應該都有1.0的規範的平臺。這可以幫助你處理你的情況,只要你正在尋找名字等東西。lengthNorm沒有任何好處。

+0

這看起來很有希望。它被設置在IndexWriter級別,但不是針對特定字段,所以如果我有一個大的其他文本字段(可能是傳記或者適合這裏例子的東西),那麼我將不得不爲SweetSpotSimilarity使用它,對嗎? – user605331 2012-02-15 16:29:52