我正在使用 Solr 4.6.0,我正在尝试获取按年份分组的最常见术语。由于我的停用词可能会经常更改,因此我不会在索引时应用停用词。相反,所有动态单词列表(例如停用词、原词和同义词)都会在查询时使用。但是,尽管停用词列表包含“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>
最佳答案
不是因为你的询问吗?
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>
关于Solr 方面在查询时忽略停用词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21061344/