如何在haystack 2.0中按字符串列表进行过滤?
在使用Solr的Haystack 1.2中,如果我有这个代码:
result = SearchQuerySet().models(MyModel).filter(my_field__in=['A', 'B', 'C'])
结果将完全返回my_field等于'A','B'或'C'的对象。相反,在使用Solr的Haystack 2.0中,我们将获得my_field为'A','A something','B','B something'的对象。我需要保留干草堆1.2的行为。有什么想法吗?
如果我在Haystack 2.0中使用:
result = SearchQuerySet().models(MyModel).filter(my_field=Exact('A'))
我将获得my_field等于'A'的对象。好!但是我找不到一个带有精确值的过滤器的解决方案。
我需要你的帮助。谢谢你。
答案 0 :(得分:0)
我找到了一个解决方案。在 Haystack 2.0 中,为solr生成的schema.xml具有与默认文本字段相关的下一个定义:
<fieldType name="text_en" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory"
ignoreCase="true"
words="lang/stopwords_en.txt"
enablePositionIncrements="true"
/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EnglishPossessiveFilterFactory"/>
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
<!-- Optionally you may want to use this less aggressive stemmer instead of PorterStemFilterFactory:
<filter class="solr.EnglishMinimalStemFilterFactory"/>
-->
<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"
enablePositionIncrements="true"
/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EnglishPossessiveFilterFactory"/>
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
<!-- Optionally you may want to use this less aggressive stemmer instead of PorterStemFilterFactory:
<filter class="solr.EnglishMinimalStemFilterFactory"/>
-->
<filter class="solr.PorterStemFilterFactory"/>
</analyzer>
</fieldType>
在 Haystack 1.2 中,为solr生成的schema.xml具有另一个定义:
<fieldType name="text" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_en.txt"/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt"/>
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<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.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt"/>
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
</analyzer>
</fieldType>
如果您比较两个定义中的分析器,您可以检查 Haystack 1.2 版本是否使用 solr.WhitespaceTokenizerFactory , Haystack 2.0 版本使用<强> solr.StandardTokenizerFactory 强>
为了保持Haystack 1.2在Haystack 2.0中的行为,你可以创建一个名为的新文本字段类型,例如“text_exact”,其中包含与Haystack 1.2相同的文本字段定义内容,然后将schema.xml中的所有文本字段关联起来用“text_en”改为“text_exact”。
从这个版本:
<field name="sales_user" type="text_en" indexed="true" stored="true" multiValued="false" />
我们将获得此其他版本:
<field name="sales_user" type="text_exact" indexed="true" stored="true" multiValued="false" />
Haystack 2.0官方文档没有为这一重大变化提供解决方案。在专门从Haystack 1.x迁移到2.x的部分中包含一些这样的例子会很有趣。
答案 1 :(得分:0)
我使用的是Haystack 2.4.1。 我遇到了类似的问题。原因是不应该对该领域进行分析。
使字段索引“not_analyzed”#39;将索引参数传递为False。 因此,在索引字段时,我使用了以下参数。
field_name = indexes.CharField(model_attr='db_field',indexed=False)
这样field_name将变为“未分析”。
之后,您将应用您的查询。