You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按BigText出现频率对Django QuerySet进行排序?

解决方案

要实现按bigtext字段的出现频率降序排序(频率高的在前,同一bigtext的条目聚合在一起),可以通过Django ORM的窗口函数或子查询统计两种方式实现,以下是具体修改:

方法1:使用窗口函数(推荐,简洁高效,需数据库支持Window函数,如PostgreSQL、MySQL 8.0+)

修改get_queryset方法如下:

from django.db.models import Q, Count, Window, F
from rest_framework import mixins, viewsets

class BigTextKeywordViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
    queryset = BigTextKeyword.objects.all()
    serializer_class = BigTextKeywordSerializer

    def get_queryset(self):
        keyword_filter = Q()
        search_content = self.request.query_params.get('search_content', '')

        for term in search_content.split(' '):
            keyword_filter |= Q(keyword__icontains=term)

        keywords = Keyword.objects.filter(keyword_filter)
        
        # 核心修改:添加频率统计并排序
        result = self.queryset.filter(keyword__in=keywords).annotate(
            # 窗口函数:统计当前bigtext在结果集中的出现次数
            bigtext_frequency=Window(
                expression=Count('bigtext'),
                partition_by=F('bigtext_id')
            )
        ).order_by('-bigtext_frequency', 'bigtext_id')
        
        return result

方法2:使用子查询统计(兼容旧版数据库,如MySQL 5.x)

如果你的数据库不支持Window函数,可改用子查询统计每个bigtext的出现次数:

from django.db.models import Q, Count, Subquery, OuterRef
from rest_framework import mixins, viewsets

class BigTextKeywordViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
    queryset = BigTextKeyword.objects.all()
    serializer_class = BigTextKeywordSerializer

    def get_queryset(self):
        keyword_filter = Q()
        search_content = self.request.query_params.get('search_content', '')

        for term in search_content.split(' '):
            keyword_filter |= Q(keyword__icontains=term)

        keywords = Keyword.objects.filter(keyword_filter)
        
        # 子查询:统计每个bigtext在结果集中的出现次数
        count_subquery = BigTextKeyword.objects.filter(
            bigtext=OuterRef('bigtext'),
            keyword__in=keywords
        ).values('bigtext').annotate(count=Count('id')).values('count')
        
        # 核心修改:关联统计结果并排序
        result = self.queryset.filter(keyword__in=keywords).annotate(
            bigtext_frequency=Subquery(count_subquery)
        ).order_by('-bigtext_frequency', 'bigtext_id')
        
        return result

说明

  • 两种方法都会为每个BigTextKeyword对象添加bigtext_frequency字段,表示该bigtext在查询结果中的出现次数。
  • 排序规则:先按bigtext_frequency降序(频率高的在前),再按bigtext_id排序(确保同一bigtext的条目聚合在一起)。
  • 最终结果会和你给出的预期示例一致:同一bigtext的所有条目连续排列,且出现次数多的bigtext组排在前面。

内容的提问来源于stack exchange,提问作者Mateus Alves de Oliveira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 04:45:46