首页 > 解决方案 > 在 Django 中按有序用户名搜索

问题描述

我想按用户名过滤用户并按相关性排序。用户名与查询完全匹配的用户应该是第一个,然后是查询开头的用户名,最后是包含查询的用户名。

承认我有以下用户名的用户:“Phoenix123”、“Phoenix”、“i_m_phoenix”、“phoenix123”、“ImPhoenix”和“phoenix”

如果我想搜索用户名包含“Phoenix”的用户,我想要一组用户名按以下顺序排列的用户:“Phoenix”、“phoenix”、“Phoenix123”、“phoenix123”、“ImPhoenix”、“ i_m_phoenix"

我试过这个:如何链接 Django 查询集保留单个订单

    user_perfect = Q(username__exact=username)  # get Phoenix if exists
    user_perfect_to_lower = Q(username__iexact=username)  # get phoenix if exists
    users_starting_perfect = Q(username__startswith=username)  # get Phoenix123 if exists
    users_starting_lower = Q(username__istartswith=username)  # get phoenix123 if exists
    users_containing_perfect = Q(username__contains=username)  # get ImPhoenix if exists
    users_containing_lower = Q(username__icontains=username)  # get im_phoenix if exists

    result = (
        User.objects.filter(
            user_perfect | user_perfect_to_lower | users_starting_perfect | users_starting_lower |
            users_containing_perfect | users_containing_lower).annotate(
            search_type_ordering=Case(
                When(user_perfect, then=Value(6)),
                When(user_perfect_to_lower, then=Value(5)),
                When(users_starting_perfect, then=Value(4)),
                When(users_starting_lower, then=Value(3)),
                When(users_containing_perfect, then=Value(2)),
                When(users_containing_lower, then=Value(1)),
                default=Value(-1),
                output_field=IntegerField(),
            )
        ).order_by('-search_type_ordering').distinct()[:10]
    )

但是如果我打印结果,则 users_starting_lower 和 users_ contains_lower 的 search_type_ordering 字段是错误的:

<QuerySet [{'username': 'Phoenix', 'search_type_ordering': 6}, 
{'username': 'phoenix', 'search_type_ordering': 5}, 
{'username': 'Phoenix123', 'search_type_ordering': 4}, 
{'username': 'phoenix123', 'search_type_ordering': 4}, 
{'username': 'ImPhoenix', 'search_type_ordering': 2}, 
{'username': 'i_m_phoenix', 'search_type_ordering': 2}]>

标签: pythondjangodjango-rest-frameworkdjango-queryset

解决方案


我有同样的问题。试试这个方法:

不太理想的比赛应该给你1分。几乎弱点比赛给你 10 = 10 分。下一场比赛给你 100 分,最想要的比赛给你 10 * (match cares num - 1) 分。

我已经在单独的字段中注释了这一点,然后在同一个查询集中将它总结在另一个带注释的字段中。然后按总和排序。

如果您需要实施帮助,请告诉我。我会尝试安装 Django 并记住如何使用它)

顺便说一句,这不是像这样在数据库中搜索的最佳主意。我已经使用上述方法改变了主意。最好的方法是使用 FTS 搜索引擎,如 Elasticaarch/Algolia/Sphinx 等


推荐阅读