2010-01-29 110 views
10

是否有可能將Django Haystack搜索與「內置」QuerySet過濾器操作相結合,特別是使用QQuery實例和SearchQuerySet不支持的查找類型進行過濾?以任意次序:像QuerySet一樣過濾Django Haystack結果?

haystack-searched -> queryset-filtered 

queryset-filtered -> haystack-searched 

瀏覽Django的草堆文件並未給出任何指示如何做到這一點。

回答

10

你可以根據草堆搜索結果篩選查詢集,使用對象的PK:

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

不知道如何擴展,但對於小結果集(幾百,在我的情況) ,這工作正常。

+6

對此,您的結果將按ID排序,您將失去針對性。 – dzen 2011-05-09 08:04:53

+0

@dzen在保持相關性排名的同時,最佳做法是什麼? – 2011-07-14 22:21:17

+5

這不會縮放。我假設查詢時間太長 - 有幾千個ID會有0個結果。 – 2012-03-06 02:02:12

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 2011-09-12 20:20:38

+0

類似於「SELECT * FROM bla WHERE id in(12,132,1251)」這樣有效,打開(也許)一個新的套接字,從那裏獲取數據? – dzen 2011-09-12 20:47:19

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