我試圖創建一個查詢,並根據權重的自定義計算對其進行排序。Django加權查詢(註釋值)
我需要一些幫助,因爲該解決方案我來確實工作,但性能並不在那裏,我想它是
我已經是一個媒體對象。它有相關的評論,喜歡和訂單。
什麼當前工作,但一個完整的哈克爛攤子以下查詢:
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'))
但類似操作,不可能(試圖與不求和()有一些變化 - Django的總是抱怨註解值是不同的型。
通過我們使用Django 1.8本項目的方式。
是否有一個良好的單一查詢的形式給出,這是讓我所需的排序權重?
編輯:
我的最終解決方案(感謝Назар)
media_list = Media.objects \
.select_related('user', 'user__image', 'image', 'currency') \
.filter(user__in=suggested_users) \
.filter(created_at__gt=seven_days_ago) \
.exclude(sold=True) \
.annotate(order_count = Count('orders', distinct=True)) \
.annotate(comment_count = Count('comments', distinct=True)) \
.annotate(like_count = Count('likes', distinct=True)) \
.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()
非常感謝。 是的,它有點醜,但ExpressionWrapper做的工作! 只有一個音符(有點奇怪)neede dto包裹initial_weight和ExpressionWrapper!我將在最終解決方案中進行編輯。 PS我需要select_related用於其他目的,但它不需要的事實也很有價值!太感謝了。 –
很高興幫助。如果有人遇到你的問題,我也會更新答案。 –