为了使用 Solr 实现一定程度的容错,我已经开始使用NGramFilterFactory
. 以下是来自的有趣位schema.xml
:
<field name="text" type="text" indexed="true" stored="true"/>
<copyField source="text" dest="text_ngram" />
<field name="text_ngram" type="text_ngram" indexed="true" stored="false"/>
<fieldType name="text_ngram" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.KeywordTokenizerFactory" />
<filter class="solr.NGramFilterFactory" minGramSize="3" maxGramSize="3" />
</analyzer>
</fieldType>
我正在使用EDisMax
带有几乎库存配置的查询处理程序。以下是来自的有趣行solrconfig.xml
:
<requestHandler name="/browse" class="solr.SearchHandler">
<lst name="defaults">
<!-- Query settings -->
<str name="defType">edismax</str>
<str name="qf">
name name_ngram^0.001
</str>
<str name="mm">100%</str>
<str name="q.op">AND</str>
...
这很好用,但是给了我很多不相关的结果。使用 Solr 的分析功能,我认为我已经将问题归结为以下原因:
查询被分解为 NGram。然后 Solr 搜索字段中的标记化查询text
或字段中的 NGram 之一text_ngram
。搜索“某物”时,使用debug=query
将打印出以下内容:parsedquery
(+DisjunctionMaxQuery(((text_ngram:som text_ngram:ome text_ngram:met text_ngram:eth text_ngram:thi text_ngram:hin text_ngram:ing) | text:something)))/no_coord
如果我没看错,这意味着要么
- 其中一个 Ngram 需要匹配或
- 原始查询(标记化)需要匹配
现在这也会发现像“以太网”这样的项目,因为其中一个 NGram ( eth
) 是相同的。
我的问题是:如何为 NGram 匹配设置更高的阈值?有没有办法说“仅在查询中至少 90% 的 NGram 匹配时才返回该项目”?确保 100% 的 NGram 匹配没有意义,因为这会有效地破坏容错。
我想到的另一种方法是仅返回相对于最高结果高于某个分数阈值的结果。这是因为与“ethernet”相比,“something”项目将具有非常高的相关性。那么有没有办法连接到 Solr 以仅返回具有例如的结果。至少是第一名的分数的 1/100?我读到有一种方法可以提供自定义HitCollector
,但我真的找不到任何关于此的信息。
谢谢!