2011-10-20 157 views
2

我正在構建一個應用程序,它使用solr將較長的查詢(通常是完整的句子)與幾乎總是較短的索引文檔(搜索詞)匹配。所以,我的問題看起來像是「現在我應該買房子,而房價低,我們2年前提交了BR,現在租了一些房貸貸款」,我的索引文件就像「買房子」,「房子貸款利率「。solr dismax短語搜索

我認爲正確的做法是使用帶狀皰疹,dismax分析器和高度提升的「pf」字段。所以,我有一個「正常的」文本字段,kw_stopped(solr 3.4中的text_en)和一個非常積極的停用詞列表,以及一個kw_phrases字段,它的意思是這個詞組帶有shingles。它的定義是這樣的:

<fieldType name="shingle" class="solr.TextField" positionIncrementGap="100"> 
    <analyzer type="index"> 
    <tokenizer class="solr.WhitespaceTokenizerFactory"/> 
    <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" 
    catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/> 
    <filter class="solr.LowerCaseFilterFactory"/> 
    <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/> 
<filter class="solr.ShingleFilterFactory" maxShingleSize="8" outputUnigrams="false"/> 
    </analyzer> 
    <analyzer type="query"> 
    <tokenizer class="solr.WhitespaceTokenizerFactory"/> 
    <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/> 
    <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" 
    catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/> 
    <filter class="solr.LowerCaseFilterFactory"/> 
    <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/> 
<filter class="solr.ShingleFilterFactory" maxShingleSize="8" outputUnigrams="false"/> 
    </analyzer> 
</fieldType> 

和我的架構領域是這樣的:

<field name="kw_stopped" type="text_en" indexed="true" omitNorms="True" /> 
<!-- keywords almost as is - to provide truer match for full phrases --> 
<field name="kw_phrases" type="shingle" indexed="true" omitNorms="True" /> 

我的搜索處理程序的配置是這樣的:

<requestHandler name="edismax" class="solr.SearchHandler" default="true"> 
    <lst name="defaults"> 
    <str name="defType">edismax</str> 
    <str name="echoParams">explicit</str> 
    <float name="tie">0.1</float> 
    <str name="fl"> 
    keywords 
    </str> 
    <str name="mm">1</str> 
    <str name="qf"> 
    kw_stopped^1.0 kw_phrases^5.0 
    </str> 
    <str name="pf"> 
    kw_phrases^50.0 
    </str> 
    <int name="ps">3</int> 
    <int name="qs">3</int> 
    <str name="q.alt">*:*</str> 
</lst> 
</requestHandler> 

當我打開debugQuery,我注意到除非查詢和文檔完全相同,否則「kw_phrases」是絕不匹配。解析後的查詢還顯示,查詢中的每個標記都顯示爲「kw_stopped」的單個DisjunctionMaxQuery子句,但所有的帶狀皰疹都置於kw_phrases字段的一個鉅子語句中。

我理解的差距在哪裏?我該如何做這項工作?

謝謝! Vijay

回答

4

如果您使用長句子搜索較短的文檔,您似乎會很好。

  • 使用Edismax query parser
  • 使用mm value to very low value or 0%,使得行爲是相同或即任何的話。您可以更改它以匹配至少2或3個單詞,以防止單個單詞匹配被返回的單詞。
  • 這將允許您控制如何匹配搜索字符串中的術語以返回文檔。
  • 使用pf(短語字段)匹配具有完全匹配的較高文檔。
  • 而不是顯式拼接過濾器,使用pf2和pf3(疊瓦式短語域)字段來匹配較高的文檔,這些文檔具有與兩個或三個單詞組合的拼塊匹配的較高文檔。
  • 使用ps(短語斜率)值爲短語匹配提供適當的slop值。

當然,您需要一個不錯的停用詞過濾器列表來防止索引和搜索時間內的通用術語匹配。

+0

感謝您的回答。我終於嘗試了pf2和pf3,這似乎給出了正確的結果。然而,「pf」似乎並不適用於dismax和shielded,我不明白爲什麼? –