Solr查询:单一术语与短语

时间:2015-08-24 07:01:17

标签: solr edismax

在我们基于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之前,我是否通过对单词进行标记来解决问题(可能是性能问题)? 也许用单一术语和短语来思考是错误的,我们应该留给用户来决定?

2 个答案:

答案 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应用程序的用户提供最佳的首选查询解析器

如果这确实是默认选择,那将会有所帮助。