为了使用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的分析功能,我认为我已经将问题归结为以下原因:
查询被分解为NGrams。然后Solr在text
字段中搜索标记化查询或在text_ngram
字段中搜索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匹配时才返回项目"?确保NGrams的100%匹配是没有意义的,因为这将有效地扼杀容错能力。
我想到的另一种方法是只返回相对于最高结果高于某个分数阈值的结果。这是因为与"以太网"相比,"某物"这一项将具有非常高的相关性。那么,有没有一种方法可以让Solr只返回那些至少是最高成绩的1/100分的成绩呢?我读到有一种方法可以提供自定义的HitCollector
,但我真的找不到任何关于这方面的信息。
谢谢!
这个想法是为了实现某种容错搜索。当有人搜索"someting"时,应该会找到"something"
Solr的SpellChecker进行模糊搜索,您可以设置阈值http://wiki.apache.org/solr/SpellCheckComponent。