2010-01-29 3 views
10

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

haystack-searched -> queryset-filtered 

или

queryset-filtered -> haystack-searched 

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

ответ

10

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

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}); 

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

+6

с этим, ваши результаты будут отсортированы по идентификаторам, и вы потеряете уместность. – dzen

+0

@dzen, что лучший способ сделать это, сохраняя при этом ранжирование релевантности? –

+5

Это не масштабируется. Я предполагаю, что запрос слишком длинный - с несколькими тысячами идентификаторов будет 0 результатов. –

0

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

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

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

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

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

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

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

+1

Если вы запустите searchqueryset.load_all(), то все объекты будут предварительно загружены из базы данных максимально эффективно, а не по одному за раз. – melinath

+0

С чем-то вроде «SELECT * FROM bla WHERE id in (12, 132,1251)». Так эффективно, чтобы открыть (возможно) новый сокет, получить данные оттуда? – dzen

1

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

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 

 Смежные вопросы

  • Нет связанных вопросов^_^