在我们基于Solr的搜索中,我们已经开始使用短语。 例如,当用户键入
时blue dress
然后Solr查询将
title:"blue dress" OR description:"blue dress"
我们现在要删除停用词。使用默认的StopFilterFactory,查询
the blue dress
将匹配包含“蓝色连衣裙”或“蓝色连衣裙”的文件。
但是,在输入时
blue the dress
然后它与包含“blue dress”的文档不匹配。
我开始怀疑我们是否应该只使用单一术语进行搜索。也就是说,将上述用户搜索转换为
title:the OR title:blue OR title:dress OR description:the OR description:blue OR description:dress
我有点不愿意这样做,因为它似乎在做StandardTokenizerFactory的工作。
这是我的schema.xml:
<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
<filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="25" />
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.SnowballPorterFilterFactory" language="English" />
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
<filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="25" />
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.SnowballPorterFilterFactory" language="English" />
</analyzer>
</fieldType>
标题和说明字段均为 text_general 类型。
单个术语是否在Solr中搜索标准搜索方式?在调用Solr之前,我是否通过对单词进行标记来解决问题(可能是性能问题)? 也许用单一术语和短语来思考是错误的,我们应该留给用户来决定?
答案 0 :(得分:1)
你偶然发现的事实是,stopwordfilter阻止了对停用词的索引,但是它们的位置仍被编入索引。类似于spaceholder的东西存储在出现停用词的索引中。
所以当你把它放到索引
时蓝色连衣裙
它将被编入索引
*蓝色连衣裙
当您提交短语
时也会发生同样的情况&#34;蓝色礼服&#34;
作为查询。它将被视为
&#34;蓝色*连衣裙&#34;
现在Solr比较了这两个片段并且它不匹配,因为*处于错误的位置。
在Solr 4.4之前,过去通过在enablePositionIncrements="true"
as described by Pascal Dimassimo中设置StopFilterFactory
来解决此问题。显然,有一个重构确实将StopFilterFactory上的选项打破为discussed on SO and Solr's Jira。
<强>更新强> 阅读 Extended Dis Max Query Parser 的参考文档时,我发现了这个
停用词参数
一个布尔参数,指示在解析查询时是否应该遵守查询分析器中配置的StopFilterFactory:如果为false,则忽略查询分析器中的StopFilterFactory。
我会检查这是否有助于解决问题。
答案 1 :(得分:0)
虽然如果查询被拆分为多个 title:term 语句,初始方法可能会有效,但这很容易出错(因为令牌可能在错误的位置被拆分)并且也是重复的,可能很糟糕,内置的标记器完成的工作。
正确的方法是按原样维护初始查询,并依赖Solr配置来正确处理它。这是有道理的,但困难在于我想指定我想要搜索的字段。事实证明,使用默认查询解析器无法做到这一点,对于字段列表,使用的是LuceneQParserPlugin(令人困惑的是,有一个名为fl的参数)用于指定返回的字段,而不是要搜索的字段。
要完成,必须提到可以使用copyField configuration is schema.xml模拟要搜索的参数列表。我觉得这个非常优雅也不够灵活。
优雅的解决方案是使用ExtendedDisMax query parser,即edismax。有了它,我们可以按原样维护查询,并充分利用模式中的配置。在我们的例子中,它看起来像这样:
SolrQuery solrQuery = new SolrQuery();
solrQuery.set("defType", "edismax");
solrQuery.set("q", query); // ie. "blue the dress"
solrQuery.set("qf", "description title");
根据this page:
(e)Dismax通常为面向Solr应用程序的用户提供最佳的首选查询解析器
如果这确实是默认选择,那将会有所帮助。