在 Solr (3.3) 中,是否可以通过 EdgeNGramFilterFactory
逐个字母地搜索字段?并且对短语查询也很敏感?
例如,我正在寻找一个字段,如果包含“contrat informatique”,则会在用户键入时找到该字段:
目前,我做了这样的事情:
<fieldtype name="terms" class="solr.TextField">
<analyzer type="index">
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/>
<tokenizer class="solr.LowerCaseTokenizerFactory"/>
<filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="15" side="front"/>
</analyzer>
<analyzer type="query">
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/>
<tokenizer class="solr.LowerCaseTokenizerFactory"/>
</analyzer>
</fieldtype>
...但它在短语查询上失败了。
当我查看 solr admin 中的模式分析器时,我发现“contrat informatique”生成了以下标记:
[...] contr contra contrat in inf info infor inform [...]
因此查询适用于“contrat in”(连续标记),而不适用于“contrat inf”(因为这两个标记是分开的)。
我很确定任何类型的词干提取都可以用于短语查询,但是在
EdgeNGramFilterFactory
之前我找不到要使用的正确过滤器标记器.
最佳答案
默认情况下,由于查询 slop 参数 = 0,精确短语搜索不起作用。
搜索短语 '"Hello World"' 它搜索具有连续位置的术语。
我希望 EdgeNGramFilter 有一个参数来控制输出定位,这看起来像一个旧的 question .
通过将 qs 参数设置为某个非常高的值(超过 ngram 之间的最大距离),您可以恢复短语。这部分解决了允许短语但不准确的排列的问题。
因此,搜索“contrat informatique”将匹配诸如“...contract disabled. Informatique...”之类的文本
支持精确我最终使用的短语查询 separate fields for ngrams .
所需步骤:
定义单独的字段类型来索引常规值和克数:
<fieldType name="text" class="solr.TextField" omitNorms="false">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="ngrams" class="solr.TextField" omitNorms="false">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="15" side="front"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
告诉 solr copy fields索引时:
您可以为每个字段定义单独的 ngrams 反射:
<field name="contact_ngrams" type="ngrams" indexed="true" stored="false"/>
<field name="product_ngrams" type="ngrams" indexed="true" stored="false"/>
<copyField source="contact_text" dest="contact_ngrams"/>
<copyField source="product_text" dest="product_ngrams"/>
或者您可以将所有 ngram 放入一个字段:
<field name="heap_ngrams" type="ngrams" indexed="true" stored="false"/>
<copyField source="*_text" dest="heap_ngrams"/>
请注意,在这种情况下,您将无法分离助推器。
最后一件事是在查询中指定 ngrams 字段和助推器。
一种方法是配置您的应用程序。
另一种方法是在 solrconfig.xml 中指定“附加”参数
<lst name="appends">
<str name="qf">heap_ngrams</str>
</lst>
关于Solr:使用 EdgeNGramFilterFactory 的精确短语查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7612889/