【发布时间】:2011-12-29 13:20:16
【问题描述】:
我在 schema.xml 中使用以下过滤器:
<filter class="solr.EdgeNGramFilterFactory" minGramSize="4" maxGramSize="15" side="front"/>
如何提升更长的 ngram?例如,当我搜索“bookpage”时,包含“bookpage”的文档的评分应该比只有“book”的文档高很多。
【问题讨论】:
我在 schema.xml 中使用以下过滤器:
<filter class="solr.EdgeNGramFilterFactory" minGramSize="4" maxGramSize="15" side="front"/>
如何提升更长的 ngram?例如,当我搜索“bookpage”时,包含“bookpage”的文档的评分应该比只有“book”的文档高很多。
【问题讨论】:
我不知道根据术语长度动态提升的方法(即,使用函数查询运算符)。我怀疑没有。
也就是说,我经常想近似您正在寻找的逻辑:长期匹配应该有更高的语义权重。
最常见的是,我会将文本值索引到两个不同的字段中。一个是没有 ngram 的最小处理文本字段。另一个类似,但也是用 ngrams 处理的。
以下是我以这种方式使用的模式的一些示例摘录。对于针对此架构的搜索,我会大幅提升 text 字段而不是 text_ngram。因此,任何与 text 字段的匹配都会极大地影响相关性,而与 text_ngram 的匹配仍然可以获得可能相关的结果。
<?xml version="1.0" encoding="UTF-8"?>
<schema name="Sunspot Customized NZ" version="1.0">
<types>
<!--
A text type with minimal text processing, for the greatest semantic
value in a term match. Boost this field heavily.
-->
<fieldType name="text" class="solr.TextField" omitNorms="false">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory" />
<filter class="solr.StandardFilterFactory" />
<filter class="solr.LowerCaseFilterFactory" />
</analyzer>
</fieldType>
<!--
Looser matches with NGram processing for substrings of terms and synonyms
-->
<fieldType name="text_ngram" class="solr.TextField" omitNorms="false">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory" />
<filter class="solr.StandardFilterFactory" />
<filter class="solr.LowerCaseFilterFactory" />
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true" />
<filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="6" side="front" />
</analyzer>
</fieldType>
<!-- other stuff -->
</types>
<fields>
<!-- id, other scalar values -->
<!-- catch-all for the text and text_ngram types -->
<field name="text" stored="false" type="text" multiValued="true" indexed="true" />
<field name="text_ngram" stored="false" type="text_ngram" multiValued="true" indexed="true" />
<!-- various dynamicField definitions -->
<!-- sample dynamicField definitions for text and text_ngram -->
<dynamicField name="*_text" type="text" indexed="true" stored="false" multiValued="false" />
<dynamicField name="*_text_ngram" type="text_ngram" indexed="true" stored="false" multiValued="false" />
</fields>
<!-- copy text fields into my text and text_ngram catch-all fields -->
<copyField source="*_text" dest="text" />
<copyField source="*_text" dest="text_ngram" />
</schema>
这不是您要寻找的,但您可以使用类似的方法。
例如,创建一个由 NGram 处理的中间字段类型(例如长度为 1-3、4-6、7-9)的小型集合,并相应地提高它们的值。
【讨论】:
copyField 指令非常强烈地暗示了这种效果。我经常认为精确术语匹配具有最强的语义价值,其中同义词、ngram、词干等都是“扩展”搜索结果的各种方法,以防错过确切的术语。