6

尝试通过布尔值过滤 SearchQuerySet 对我不起作用。(我在测试时使用提供的“简单”后端搜索引擎。)

我有一个像这样的索引:

class MyIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    has_been_sent = indexes.BooleanField(model_attr='has_been_sent')
    # other fields

    def get_model(self):
        return MyModel

我使用自定义表单进行搜索:

BOOLEAN_OPTIONS = [ ('either', 'Either'), ('yes', 'Yes'), ('no', 'No') ]

class MyModelSearchForm(SearchForm):
    # other fields
    has_been_sent = forms.ChoiceField( widget = forms.Select(), label = 'Sent?', choices=BOOLEAN_OPTIONS )

def search(self):
    sqs = super(MyModelSearchForm, self).search()

    if not self.is_valid(): return self.no_query_found()

    sqs = sqs.models(MyModel) # cuts out other models from the search results
    if self.cleaned_data['has_been_sent'] != 'either':
        if self.cleaned_data['has_been_sent'] == 'yes': sent = True
        else: sent = False
        sqs = sqs.filter(has_been_sent=sent)

    return sqs

如果我在表单中将 has_been_sent 选项设置为 Yes 或 No,我总是得到 0 个结果,这显然是错误的。我也尝试过shell,但没有运气。sqs.filter(has_been_sent=True)并且sqs.filter(has_been_sent=False)都返回一个空列表,即使sqs.values('has_been_sent')清楚地显示了一堆具有真值的记录 has_been_sent。甚至更奇怪的是,sqs.filter(has_been_sent='t')返回记录的子集,以及“f”、“a”和不相关的字母,如“j”!我完全不知所措。有人对 Haystack 的这类问题有过经验吗?

在相关说明中,您过滤的字段是SearchQuerySet().filter()从索引字段(在 search_indexes.py 中)还是模型字段(在它们各自的 models.py 中)?

编辑:

我一直在尝试通过 Django 的 manage.py shell 测试我的过滤器,但我认为我做错了。它似乎没有跟随我的 search_indexes.py,因为我在那里使用 index_queryset() 方法将它限制为 MyModel 的一个子集,但我在 shell 中获得了 MyModel 的所有对象。

>>> from haystack.query import SearchQuerySet
>>> from myapp.models import MyModel
>>> sqs = SearchQuerySet().models(MyModel)

然后进行一些测试:

>>> len(sqs) # SHOULD be 5, due to the index_queryset() method I defined in search_indexes.py
17794
>>> sqs.filter(has_been_sent='true') # Same happens for True, 'TRUE', and all forms of false
[]
>>> len(sqs.filter(not_a_real_field='g')) # Made-up filter field, returns a subset somehow??
2591
>>> len(sqs.filter(has_been_sent='t'))
3621
>>> len(sqs.filter(has_been_sent='f'))
2812

因为我在过滤假字段时得到了一个子集,所以我认为它不会将 has_been_sent 识别为我的过滤器字段之一。特别是因为 't' 和 'f' 的结果加起来不等于总数,这是应该的,因为所有记录都需要该布尔字段。我在测试中错过了一步吗?

4

2 回答 2

7

尝试过滤为字符串truefalse在查询中,这是 haystack 中已知的限制,我不确定这是否已修复,而不是:

sqs.filter(has_been_sent=True)

做这个:

sqs.filter(has_been_sent='true') # true or false in lowercase

PS 当您SearchQuerySet().filter()根据文件中定义的字段进行过滤时search_indexes.py

于 2013-10-07T21:19:44.853 回答
1

看来问题出在 Simple 后端。我安装了 Haystack 并将其切换到 Whoosh,这个问题就解决了。(现在 SearchQuerySet().models() 不起作用,但这显然是 Haystack + Whoosh 的一个记录错误。)

编辑:由于 Whoosh 的进一步问题,我改用 Solr 4.5.1 作为我的后端。现在一切都按预期工作。

于 2013-10-08T18:55:24.977 回答