gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 03:32:19 25 4
gpt4 key购买 nike

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

我需要一些帮助,因为我找到的解决方案确实有效,但性能不是我想要的

我拥有的是一个 Media 对象。它有相关的评论、点赞和订单。

当前有效但完全困惑的是以下查询:

    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 总是提示注释值的类型不同。

顺便说一句,我们在这个项目中使用 django 1.8。

是否有一个好的单查询方法来获得我想要的排序权重?

最佳答案

首先,您需要确保除法会产生 float (不进行舍入)。你需要这样的东西(disgracefully stolen here):

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_latedselect_realted,django自己会处理这些事情(但是,这只是我的猜测 - 如果您稍后在代码中实际使用这些外键,那么这是合理的)。

关于python - Django加权查询(带注释的值),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40759037/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com