【问题标题】:Add an element of randomness to ordering in SQL, django在 SQL、django 中为排序添加随机元素
【发布时间】:2014-10-30 17:52:29
【问题描述】:

我正在使用 Python/Django,但我怀疑这必须在 mysql 级别上完成。

如果我有这样的模型:

class Article(models.Model):
    title = models.CharField(max_length = 256)
    rating = models.IntegerField(default=0)

我想查询评分最高的文章,但我想添加一个随机元素。我不只是希望他们所有人的评分都达到 100 分(满分 100 分)。

如果我在 python 中这样做,我会做类似的事情

articles = Article.objects.all()
#multiply each rating by a random multiplier and store that value in a tuple with the article
articles = [(random.random()*article.rating, article) for article in articles] 
#sort by the calculated rating*random value
articles.sort(key=lambda tup: tup[0], reverse=True) 

也许这是我能做的最好的了。但是,如果我要将其降低到查询级别,这就是我目前所拥有的一切:

articles = Article.objects.extra(select={"rand_rating":'( rating * {})'.format( random.random() )})
articles = articles.extra(order_by=['rand_rating'])

乍一看我认为这可能有效,但 random.random() 数字只是将所有内容乘以相同的常数,这基本上是无用的。我查看了 sql RAND() 但从我读过的内容来看,我会遇到同样的问题,因为不是为每一行调用 RAND(),而是每个查询只调用一次。

【问题讨论】:

标签: python sql django postgresql random


【解决方案1】:

.order_by() 使用字符串 '?' 内置了随机排序:

https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.order_by

在你的情况下是:

Article.objects.order_by('?')

排序后,您可以过滤掉前 X 条记录并再次按评分排序。

【讨论】:

  • 这是随机的,但我认为结果不一样。随机排序文章然后占据上半部分,然后按评级对它们进行排序仍然会给我 100/100 的评级。而在我的算法中,获得列表前面的 50/100 的概率更大。
  • 我认为您可以将.distinct('rating') 链接到随机排序的末尾。这样就可以只找到一个 100/100 评分(或者根本找不到,例如,如果您使用 [:10] 限制到一个子集),其余的是一组随机的其他评分值。如果文章集足够大(比如 1000 篇),它会显示出不错的传播。 -- 当然,您在原始问题中要求最高评分,您可以使用.filter() 进行选择。
猜你喜欢
  • 2012-11-13
  • 2021-04-19
  • 2015-06-23
  • 1970-01-01
  • 1970-01-01
  • 2018-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多