订单查询结果startwith匹配

时间:2012-07-24 00:31:12

标签: python django django-queryset

我们正在进行网站搜索,我们使用icontains搜索字段。它的工作效果很好,但结果却没有最相关的结果。

一个例子是搜索“权力的游戏”。如果搜索是“游戏”,第一个结果可能是“Crazy Game of ...”,第二个结果是“权力的游戏”

基本上,我想使用icontains进行搜索,但按startswith排序。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

您所描述的顺序是主观的,并且没有像数据库那样的数据(我知道)。如果此类功能很重要,您可能需要查看SolrSphinx等搜索引擎,您可以在其中配置相关性分数的确定方式。

答案 1 :(得分:2)

自问这个问题以来,Django添加了新功能,现在本地处理这个用例。

您可以使用Django的QuerySet API中的以下功能通过任意比较来订购结果:

  1. Q() Object :封装可重用的查询表达式。我们的表达式将对象的字段与我们的" 游戏"进行比较。搜索价值。
  2. ExressionWrapper() :包装查询表达式,以便使用ModelField控制output_field类型。在这种情况下,类型是布尔值。
  3. annotate() :根据查询表达式的结果,为每个QuerySet对象动态添加ModelField。我们希望添加True / False字段进行排序。
  4. order_by() :按指定字段对QuerySet对象进行排序。我们希望通过带注释的字段值进行反序排序,以便首先显示True值。
  5. 
        from django.db.model import Q, ExpressionWrapper, BooleanField
    
        ....
    
        # Your original setup.
        search_term = 'Game of'
        data = MyModel.objects.filter(name__icontains=search_term)
    
        # Encapsulate the comparison expression.
        expression = Q(name__startswith=search_term)
    
        # Wrap the expression to specify the field type.
        is_match = ExpressionWrapper(expression, output_field=BooleanField())
    
        # Annotate each object with the comparison.
        data = data.annotate(my_field=is_match)
    
        # Order by the annotated field in reverse, so `True` is first (0 < 1).
        data = data.order_by('-my_field')
    
        ....