haystack 2 SearchQuerySet with filter by list with exact string

时间:2014-02-04 13:21:53

标签: solr filter django-haystack searchqueryset

如何在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'的对象。好!但是我找不到一个带有精确值的过滤器的解决方案。

我需要你的帮助。谢谢你。

2 个答案:

答案 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将变为“未分析”。

之后,您将应用您的查询。