Python 按startswith match排序的订单查询结果
我们正在进行一个站点搜索,其中我们使用Python 按startswith match排序的订单查询结果,python,django,django-queryset,Python,Django,Django Queryset,我们正在进行一个站点搜索,其中我们使用icontains搜索一个字段。它工作得很好,但是出现的结果在顶部没有最相关的结果 一个例子是搜索“权力游戏”。如果搜索是“游戏的”,第一个结果可能是“疯狂的…游戏”,第二个结果是“权力的游戏” 基本上,我想用icontains进行搜索,但按startswith排序。有什么想法吗?您描述的顺序是主观的,而且数据库中没有类似的数据(我知道)。如果像这样的功能很重要,您可能希望查看类似的搜索引擎,或者您可以在其中配置如何确定相关性分数。Django在提出此问题后
icontains
搜索一个字段。它工作得很好,但是出现的结果在顶部没有最相关的结果
一个例子是搜索“权力游戏”。如果搜索是“游戏的”,第一个结果可能是“疯狂的…游戏”,第二个结果是“权力的游戏”
基本上,我想用
icontains
进行搜索,但按startswith
排序。有什么想法吗?您描述的顺序是主观的,而且数据库中没有类似的数据(我知道)。如果像这样的功能很重要,您可能希望查看类似的搜索引擎,或者您可以在其中配置如何确定相关性分数。Django在提出此问题后添加了新功能,现在以本机方式处理此用例
您可以使用Django的QuerySet API中的以下功能通过任意比较对结果排序:
输出字段
控制模型字段
类型。在本例中,类型是布尔值True
/False
字段进行排序True
值
从django.db.model导入Q、ExpressionWrapper、BooleanField
....
#您的原始设置。
搜索词='游戏'
data=MyModel.objects.filter(name\u icontains=search\u term)
#封装比较表达式。
expression=Q(name\uu startswith=search\u term)
#换行表达式以指定字段类型。
is_match=ExpressionWrapper(表达式,输出_字段=BooleanField())
#使用比较为每个对象添加注释。
数据=数据.注释(我的字段=匹配)
#按带注释的字段反向排序,因此'True'位于第一位(0<1)。
data=data.order_by('-my_field'))
....
你说得对!黑客的解决方案是确定分数的子查询。在order子句中使用该分数。但这不是一个db友好的解决方案。
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')
....