我正在构建一个应用程序,它使用solr将较长的查询(通常是完整的句子)与索引文档(几乎总是较短的搜索词)进行匹配。所以,我的问题是"我应该在利率低的时候买房吗?"我们两年前提交了BR。现在租房,w/some sch loan debt",我的索引文件是"买房","房屋贷款利率"。
我认为正确的方法是使用shingles, 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"永远不会匹配,除非查询和文档完全相同。此外,parsedquery还显示,来自查询的每个标记都显示为"kw_stopped"的单个DisjunctionMaxQuery子句,但是所有的子句都放在kw_phrases字段的一个大子句中。
我的理解差距在哪里?我该怎么做呢?
谢谢!Vijay
如果你使用长句子来搜索较短的文档,你似乎很好。
- 使用Edismax查询解析器
- 使用mm值到非常低的值或0%,以便行为与or相同,即任何单词。您可以将其更改为匹配至少2或3个单词,以防止返回单个单词匹配的单词。
- 这将允许您控制如何匹配搜索字符串中的术语以返回文档。
- 使用pf(短语字段)匹配具有精确匹配的更高的文档。
- 使用pf2和pf3 (shingled短语字段)字段来匹配具有两个或三个单词组合的shingle匹配的文档,而不是显式的shingle过滤器。
- 使用ps(短语斜率)值为短语匹配提供足够的斜率值。
当然,您需要一个很好的停止词过滤列表,以防止在索引和搜索期间进行一般术语匹配。