当前位置: 首页 > 知识库问答 >
问题:

Django加权查询(带注释的值)

邵劲
2023-03-14

我正在尝试创建一个查询并根据自定义权重计算对其进行排序。

我需要一些帮助作为解决方案我来确实工作但性能是不是在那里我想它是

我拥有的是一个媒体对象。它有相关的评论、喜欢和命令。

以下查询目前有效,但完全是一团乱麻:

    products = (Media.objects
        .select_related(
            'image',
            'currency',
            'user',
            'user__image',
        )
        .prefetch_related('category', 'tags')
        .exclude(is_deleted=1)
        .filter(Q(category__category__in=categories) | Q(tags__tag__title=query))
        .annotate(order_count = Count('orders', distinct=True))
        .annotate(comment_count = Count('comments', distinct=True))
        .annotate(like_count = Count('likes', distinct=True))
        .annotate(weight = Count(0))
        .distinct())
    
    for m in products.iterator():
        initial_weight  = int(m.order_count)*40 + int(m.comment_count)*4 + int(m.like_count)*4 + int(m.clicks)
        m.weight        = float(float(initial_weight) - float(m.views/50))

如您所见,我正在单独注释我将使用的所有参数,然后对查询集中的每个项目进行愚蠢的遍历,这是非常次优的。

我尝试做的一件事是:

    products = (Media.objects
        .select_related(
            'image',
            'currency',
            'user',
            'user__image',
        )
        .prefetch_related('category', 'tags')
        .exclude(is_deleted=1)
        .filter(Q(category__category__in=categories) | Q(tags__tag__title=query))
        .annotate(weight = Count('orders', distinct=True) * 40 + Count('comments', distinct=True) * 4 + Count('likes', distinct=True) - F('views')/50 + F('clicks')))

但是注释中的类似操作是不可能的(尝试了一些有和没有Sum()的变体——Django总是抱怨注释值的类型不同。

是否有一个好的单一查询方法来获取我所需的排序权重?

共有1个答案

柳宏深
2023-03-14

首先,你需要确保除法会产生浮点数(没有四舍五入)。你需要这样的东西(在这里可耻地被盗):

ExpressionWrapper(
    (F('views') / Decimal(50.0), 
    output_field=FloatField()),
)

因此,查询如下所示:

products = (Media.objects
    .exclude(is_deleted=1)
    .filter(Q(category__category__in=categories) | Q(tags__tag__title=query))
    .annotate(order_count = Count('orders', distinct=True))
    .annotate(comment_count = Count('comments', distinct=True))
    .annotate(like_count = Count('likes', distinct=True))
    .annotate(weight = Count(0))
    .annotate(
        initial_weight=ExpressionWrapper(
            F('order_count') * 40 + F('comment_count') * 4 +
            F('like_count') * 4 + F('clicks'),
            output_field=FloatField()
        )
     )
    .annotate(
        views_divided=ExpressionWrapper((F('views') / Decimal(50.0), 
                                        output_field=FloatField()))
     )
    .annotate(weight=F('initial_weight') - F('views_divided'))
    .distinct())

看起来很丑,但应该可以(我认为)。

顺便说一下-如果您只需要计算权重,您实际上不必使用prefetch_relatedselect_realted,django会自己处理这些东西(然而,这只是我的猜测-如果您在代码后面实际使用这些外键,那么这是合理的)。

 类似资料:
  • 问题内容: 这是我目前最喜欢使用的一项前沿功能,并且很快就会消失。我想将子查询聚合注释到现有查询集上。在1.11之前执行此操作意味着自定义SQL或修改数据库。这是this的文档以及其中的示例: 他们在总体上进行注释,这对我来说似乎很奇怪,但是无论如何。 我正在为此而苦苦挣扎,所以我将其沸腾回到我拥有数据的最简单的真实示例中。我有,其中包含许多Space。使用会使你更快乐,但是-暂时-我仅想使用 注

  • 我对Spring中的原生查询有一个问题。我在param value中使用了带有参数nativequery=true注释@query和SQL查询。 而在RezerWacjamanager.java中: 问题是什么时候调用方法RezerWacjadao.getDoStepnosCnatypy(dataOd,dataDo)并执行此查询。我得到一个错误错误: DoStepNosCtypyListdTo.j

  • 我试图在elasticsearch spring数据中使用@query annotation来进行复杂的查询,但当我尝试下面的简单查询时,我得到了一个错误 堆栈跟踪

  • 我目前正在尝试向我的REST API添加一个新功能。 基本上,我想添加在路径末尾添加查询参数的功能,并将其转换为所有查询选项的映射,例如。 我当前的代码允许我做这样的事情 这将使用所有@pathparam作为字符串变量来生成响应。 我现在想做的是添加: 然后我会让它生成一个映射,可以和pathparam一起用来构建响应 我在想这样的事情[下图]然而@QueryParam似乎只处理一个键值,而不是它

  • 我一直试图理解HQL和JPQL之间的区别。冬眠留档在这里 建议写入选择是JPQL所必需的,但不是在HQL中。但是当我尝试在Spring数据JPA的查询注释中编写HQL或JPQL时,HQL和JPQL都可以工作。 我的理解是,既然查询注释是针对JPA的,为什么支持HQL? 或者让我换个说法- 我们可以在查询注释中编写HQL吗——Spring数据JPA支持两者吗?

  • 我正在使用注释处理器来处理方法参数的注释。 用于参数的注释类型有一个注释@参数 现在,当注释处理器运行时,我想检查参数注释()是否有参数注释。我通过执行以下代码来实现这一点。 由于某种原因,arg始终为空。是否有注释未返回的原因?