【问题标题】:Django-haystack: how do I select which index to use in a SearchQuerySet?Django-haystack:如何选择在 SearchQuerySet 中使用哪个索引?
【发布时间】:2014-07-24 22:37:22
【问题描述】:

我一直在查看 multiple indexes 上的 Haystack 文档,但我不知道如何使用它们。

本例中的主要模型是Proposal。我希望有两个返回提案列表的搜索索引:一个仅在提案本身中搜索,另一个在提案及其 cmets 中搜索。我已经这样设置了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 的单独视图?

【问题讨论】:

    标签: django django-haystack


    【解决方案1】:

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

    但您的问题似乎是关于如何查询不同模型的“SearchIndexes”。在您的示例中,如果我正确理解您的问题,您希望有一个搜索查询“proposals”和另一个“proposals”+“cmets”。

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

    例如,在您的搜索视图中,您可能希望有一个查询字符串参数,例如“content”,它指定搜索是针对“proposals”还是“everything”(proposals 和 cmets)。所以你的前端需要在调用视图时提供额外的 content 参数(或者你可以为不同的搜索使用单独的视图)。

    您的查询字符串需要如下所示:

    /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):
        results = None
        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 动态获取模型类。

    【讨论】:

    • 谢谢!如果您将Comment 添加到您的search_models 列表中,是否会在搜索结果中同时返回proposal 和cmets?我想我的问题并不清楚:我的意思是搜索结果应该始终只返回提案,但在一种情况下它应该只索引提案,在另一种情况下它应该同时索引提案及其 cmets。
    • 是的,SearchQuerySet models 方法将根据您在参数列表中提供的模型在适当的索引中搜索。如果您仅提供 Proposal,它将仅返回该内容类型的结果。提供 ProposalComment 将返回两种内容类型的结果。您的搜索视图/功能应根据您(或您的用户)想要执行的搜索来处理内容类型的查询。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 1970-01-01
    • 2011-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多