Отфильтровать результаты поиска в Django Haystack, например QuerySet?

Можно ли комбинировать поиск в Haystack Django с "встроенными" операциями фильтра QuerySet, особенно с фильтрами с экземплярами Q() и типами поиска, не поддерживаемыми SearchQuerySet? В любом порядке:

haystack-searched -> queryset-filtered

или

queryset-filtered -> haystack-searched

Просмотр документации по Haystack Django не дал никаких указаний, как это сделать.

Ответ 1

Вы можете отфильтровать ваш запрос на основе результатов поиска Haystack, используя PKs объектов:

def view(request):
  if request.GET.get('q'):
    from haystack import ModelSearchForm
    form = ModelSearchForm(request.GET, searchqueryset=None, load_all=True)
    searchqueryset = form.search()
    results = [ r.pk for r in searchqueryset ]

    docs = Document.objects.filter(pk__in=results)
    # do something with your plain old regular queryset

    return render_to_response('results.html', {'documents': docs});

Не уверен, как это масштабируется, но для небольших результирующих наборов (несколько сотен, в моем случае) это прекрасно работает.

Ответ 2

Из документов:

SearchQuerySet.load_all (сам)

Эффективно заполняет объекты в результатах поиска. Без использования этот метод, поиск БД выполняется на основе каждого объекта, в результате чего многие индивидуальные поездки в базу данных. Если используется load_all, SearchQuerySet группирует подобные объекты в один запрос, что приводит к тому, что столько запросов, сколько разных типов объектов вернулся.

http://django-haystack.readthedocs.org/en/latest/searchqueryset_api.html#load-all

Поэтому после того, как у вас есть фильтрованный SQS, вы можете сделать load_all() на нем и просто получить доступ к объектам базы данных через SearchResult.object. Например.

sqs = SearchQuerySet()
# filter as needed, then load_all
sqs = sqs.load_all()

for result in sqs:
    my_obj = result.object
    # my_obj is a your model object

Ответ 3

Если вы хотите идти в ногу с уместностью, вам нужно получить доступ к объекту из базы данных через "объект":

пример в вашем шаблоне:

{% for result in results %}
    {{ result.object.title }}
    {{ result.objects.author }}
{% endfor %}

Но это действительно плохо, поскольку сенатор сделает дополнительный запрос, например "SELECT * FROM blah WHERE id = 42" по каждому результату.

Кажется, вы пытаетесь получить этот объект из своей базы данных, потому что вы не поместили лишние поля в свой индекс, не так ли? Если вы добавите заголовок И автора в свой SearchIndex, вы можете просто использовать свои результаты:

{% for result in results %}
    {{ result.title }}
    {{ result.author }}
{% endfor %}

и избегайте некоторых дополнительных запросов.