Django Haystack - Как отфильтровать результаты поиска по логическому полю?

Попытка отфильтровать 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 значение Да или Нет в форме, я всегда получаю 0 результатов, что явно неверно. Я тоже пробовал в скорлупе, без везения. sqs.filter(has_been_sent=True) а также sqs.filter(has_been_sent=False) оба возвращают пустой список, ДАЖЕ МЫСЛЬ sqs.values('has_been_sent') четко показывает кучу записей со значениями True для has_been_sent. И даже незнакомец, sqs.filter(has_been_sent='t') возвращает подмножество записей вместе с 'f', 'a' и несвязанными буквами, такими как 'j'! Я в полной растерянности. У кого-нибудь есть опыт решения подобных проблем с Хейстек?

В соответствующей заметке есть поля, по которым вы фильтруете SearchQuerySet().filter() из полей индекса (в search_indexes.py) или из полей модели (в соответствующих им файлах models.py)?

РЕДАКТИРОВАТЬ:

Я пытался протестировать свои фильтры через оболочку manage.py в Django, но думаю, что я делаю это неправильно. Похоже, что он не следует моему search_indexes.py, поскольку я ограничил его подмножеством MyModel с помощью метода index_queryset(), но я получаю ВСЕ объекты 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' не суммируются с итогом, который он ДОЛЖЕН, так как это логическое поле является обязательным для всех записей. Я пропускаю шаг в моем тестировании?

2 ответа

Решение

Похоже, что проблема была в простом бэкэнде. Я установил и переключил Haystack на Whoosh, и эта проблема прояснилась. (Теперь SearchQuerySet(). Models() не работает, но это явно задокументированная ошибка с Haystack + Whoosh.)

Изменить: Из-за дальнейших проблем с Whoosh, я переключился на использование Solr 4.5.1 в качестве моего бэкэнда. Теперь все работает как положено.

Попробуйте отфильтровать как строку true или же false в запросе это было известным ограничением в стоге сена, и я не уверен, что это исправлено, вместо того, чтобы делать:

sqs.filter(has_been_sent=True)

Сделай это:

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

PS когда ты SearchQuerySet().filter() Вы фильтруете на основе полей, определенных в search_indexes.py файл.

Другие вопросы по тегам