Solr facets在查询时忽略停用词

时间:2014-01-11 10:50:17

标签: solr facet stop-words

我正在使用Solr 4.6.0而我正在努力获得按年份分组的最常用术语。由于我的停用词可能经常更改,因此我不会在索引时应用停用词。相反,所有动态单词列表(如停用词,protwords和同义词)都在查询时使用。但是,虽然禁止词列表包含“of”和“the”之类的术语,但它们仍显示在结果列表中(参见结果)。

问题:如果我仅在查询时使用 StopFilterFactory ,我该如何获得分面和停用过滤结果?

其他信息

如果我在索引时使用 StopFilterFactory ,一切都按预期进行。当我运行查询时,“of”和“the”等术语被过滤掉了。

我还使用Solr管理分析工具测试了 fieldtype text_en的功能,结果如预期 - “of”和“the”被过滤掉。这意味着 SearchHandler 不会以某种方式调用正确的分析器

查询

http://ip:port/solr/collection1/select?q=*:*&rows=0&facet=true&facet.pivot=year,text

结果

[..]
<lst name="facet_pivot">
  <arr name="year,text">
    <lst>
      <str name="field">year</str>
      <int name="value">2009</int>
      <int name="count">139</int>
      <arr name="pivot">
        <lst>
          <str name="field">text</str>
          <str name="value">of</str>
          <int name="count">135</int>
        </lst>
        <lst>
          <str name="field">text</str>
          <str name="value">the</str>
          <int name="count">135</int>
        </lst>
        <lst>
          <str name="field">text</str>
          <str name="value">and</str>
          <int name="count">123</int>
[..]

Schema.xml的

<field name="year" type="int" indexed="true" stored="true" />
    <field name="text" type="text_en" indexed="true" stored="true" multiValued="true" />
    [..]
    <fieldType name="text_en" class="solr.TextField" positionIncrementGap="100">
          <analyzer type="index">
            <tokenizer class="solr.StandardTokenizerFactory"/>
            <filter class="solr.LowerCaseFilterFactory"/>
            <filter class="solr.EnglishPossessiveFilterFactory"/>
            <filter class="solr.PorterStemFilterFactory"/>
          </analyzer>
          <analyzer type="query">
            <tokenizer class="solr.StandardTokenizerFactory"/>
            <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
            <filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_en.txt" />
            <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
            <filter class="solr.LowerCaseFilterFactory"/>
            <filter class="solr.EnglishPossessiveFilterFactory"/>
            <filter class="solr.PorterStemFilterFactory"/>
          </analyzer>
        </fieldType>

4 个答案:

答案 0 :(得分:1)

请参阅Solr邮件列表中的主题 - does solr support query time only stopwords?

这听起来与您的要求非常相似,他们的解决方法是在索引时启用stopFilterFactory,但是没有指定停用词文件以使其按预期工作。

答案 1 :(得分:1)

是不是因为你的查询?

http://ip:port/solr/collection1/select?q=*:*&rows=0&facet=true&facet.pivot=year,text

从我所看到的,你正在寻找一切,所以这意味着它也将返回停用词。我的意思是,如果查询传递给分析器,分析器的过滤器类只能看到

*:* 

作为查询,所以我认为它不会从查询字符串中删除任何内容。

如果您确实想要搜索所有内容,但没有任何停用词,则可以尝试使用negative query进行搜索。当然,如果您使用此功能,则需要使用不同的配置来过滤查询的任何停用词,然后您可以手动将停用词作为否定查询来过滤它们。所以你基本上都在搜索任何东西,但是遗漏了包含否定查询的结果。

但是,根据我的观点,一种简单的方法(根据我的观点更好的方式)来获得你想要的东西实际上是在字段配置中使用复制字段。但这会增加您的索引大小。所以我们在这里使用solr做的是,除了普通字段外,我们还有其他语言字段,如text_en,text_de,text_es等。我们有一个语言检测器,可以检测语言,将字段复制到适当的语言,以及运行正确的停用词过滤器。

如果您希望在schema.xml中创建一个新字段text_en_filtered,并在那里复制text_en中的文本,并在那里过滤停用词,也可以这样做。然后你可以在那个没有任何停用词的字段中搜索。

<field name="text_en_filtered" type="text_en_filtered" indexed="true" stored="false" multiValued="false"/>
<copyField source="text" dest="text_en_filtered"/>
<fieldType name="text_en_filtered" class="solr.TextField" positionIncrementGap="100">
    ... // Analyzer with stopwords filtering here..
</fieldType>

答案 2 :(得分:0)

抱歉,您的问题不明确。 所以我猜测并试图回答可能是你的问题。 以下是停用词的处理方式。如果您在索引时间内有<filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_en.txt" />,则Solr不会对停用词进行索引,并且您不会在结果方面看到这些词。此外,您需要在查询期间使用此功能进行正确匹配。

如果您在查询期间有<filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_en.txt" />,那么您只需在Solr执行查询之前从查询短语中删除停用词。

更新您对分析链的错误理解似乎是您混淆的原因。您的q参数是“”,因此,如果您在查询期间有StopFilterFactory,如上所述,您将过滤“”中的停用词,而不是查询结果。由于您正在研究文本,因此您将在结果中使用仍然符号的结尾。您需要了解查询时间分析是在QUERY上而不是在结果上。您的“文本”仍然会显示结果中显示的停用词。在这种情况下,删除您在客户端不需要的结果会更好,更容易。

答案 3 :(得分:0)

我担心你必须重新索引,除非你可以深入研究分面代码并在聚合过程之前将其过滤掉。 您可以通过将文档集减少到仅包含新案例的文档来加速处理,以防万一。