2010-01-29 111 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