Django-haystack:如何选择在SearchQuerySet中使用哪个索引?

时间:2014-07-24 22:37:22

标签: django django-haystack

我一直在浏览multiple indexes上的Haystack文档,但我无法弄清楚如何使用它们。

此示例中的主要模型是Proposal。我希望有两个搜索索引可以返回提案列表:一个只搜索提案本身,另一个搜索提案及其注释。我已按照以下方式设置search_indexes.py

class ProposalIndexBase(indexes.SearchIndex, indexes.Indexable)
    title = indexes.CharField(model_attr="title", boost=1.1)
    text = indexes.NgramField(document=True, use_template=True)
    date = indexes.DateTimeField(model_attr='createdAt')

    def get_model(self):
        return Proposal


class ProposalIndex(ProposalIndexBase):
    comments = indexes.MultiValueField()

    def prepare_comments(self, object):
        return [comment.text for comment in object.comments.all()]


class SimilarProposalIndex(ProposalIndexBase):
    pass

我在views.py搜索

def search(request):
    if request.method == "GET":
        if "q" in request.GET:
            query = str(request.GET.get("q"))
            results = SearchQuerySet().all().filter(content=query)
    return render(request, "search/search.html", {"results": results})

如何设置从特定索引获取SearchQuerySet的单独视图?

1 个答案:

答案 0 :(得分:6)

Haystack(以及其他自动生成的)文档并不是一个清晰的好例子,它与阅读电话簿一样令人兴奋。我认为您在“多个索引”中提到的部分实际上是关于访问不同的后端搜索引擎(如whoosh,solr等)以进行查询。

但您的问题似乎是关于如何查询不同模型的“SearchIndexes”。在您的示例中,如果我正确理解您的问题,您希望对“提案”进行一次搜索查询,对“提案”+“评论”进行另一次搜索查询。

我想你想看一下SearchQuerySet API,它描述了如何过滤搜索返回的查询集。有一个名为models的方法允许您提供模型类或模型类列表以限制查询集结果。

例如,在搜索视图中,您可能希望拥有一个查询字符串参数,例如“内容”,用于指定搜索是针对“提案”还是针对“所有内容”(提案和评论)。因此,您的前端需要在调用视图时提供额外的内容参数(或者您可以为不同的搜索使用单独的视图)。

您的查询字符串需要类似于:

/search/?q=python&content=proposal
/search/?q=python&content=everything

您的视图应解析 content 查询字符串参数,以获取用于过滤搜索查询结果的模型:

# import your model classes so you can use them in your search view
# (I'm just guessing these are what they are called in your project)
from proposals.models import Proposal
from comments.models import Comment

def search(request):
    if request.method == "GET":
        if "q" in request.GET:
            query = str(request.GET.get("q"))
            # Add extra code here to parse the "content" query string parameter...
            # * Get content type to search for
            content_type = request.GET.get("content")
            # * Assign the model or models to a list for the "models" call
            search_models = []
            if content_type is "proposal":
                search_models = [Proposal]
            elif content_type is "everything":
                search_models = [Proposal, Comment]
            # * Add a "models" call to limit the search results to the particular models
            results = SearchQuerySet().all().filter(content=query).models(*search_models)
return render(request, "search/search.html", {"results": results})

如果您有很多搜索索引(即许多模型中的大量内容),您可能不想在视图中对模型进行硬编码,而是使用 django中的 get_model 函数.db 动态获取模型类。