【问题标题】:In Django, how do I select 100 random records from the database? [duplicate]在 Django 中,如何从数据库中选择 100 条随机记录? [复制]
【发布时间】:2011-03-31 05:14:26
【问题描述】:
myqueryset = Content.objects.filter(random 100)

【问题讨论】:

    标签: python mysql database django


    【解决方案1】:
    Content.objects.all().order_by('?')[:100]
    

    请参阅order_by docs。另请注意,这种方法不能很好地扩展(事实上,它的扩展性非常非常糟糕)。请参阅this SO answer,了解在拥有大量数据时处理随机选择的更好方法。

    【讨论】:

    • 而且 all() 是多余的,但我不记得了。
    • 这太棒了!通过调试,我注意到它甚至生成了一个很好的查询,只抓取 20 个元素,使用 1 个查询,使用 ORDER BY RAND() 进行随机。天哪,太棒了。
    【解决方案2】:

    如果您要多次执行此操作,则需要将其设计到您的数据库中。

    如果您只做一次,您可以支付巨额罚款。这会让你得到 100 个非常好的随机属性。但是,它会占用大量内存。

    pool= list( Content.objects.all() )
    random.shuffle( pool )
    object_list = pool[:100]
    

    这是另一种算法,它也有点慢,因为它可能会搜索整个表。它根本不会使用太多内存,而且它可能不会精确到 100。

    total_count= Content.objects.count()
    fraction = 100./total_count
    object_list = [ c for c in Content.objects.all() if random.random() < fraction ]
    

    如果您想多次执行此操作,则需要向 Content 添加一个属性以允许有效过滤“随机”值。例如,您可以这样做。

    class Content( models.Model ):
        ... etc. ...
        def subset( self ):
            return self.id % 32768
    

    这会将您的数据划分为 32768 个不同的子集。每个子集是您数据的 1/32768。要获得 100 个随机项,您需要 100*32768/total_count 个数据子集。

    total_count = Content.objects.count()
    no_of_subsets= 100*32768/total_count
    object_list = Content.objects.filter( subset__lte=no_of_subsets )
    

    这是快速,并且可以重现。子集是“任意的”而不是技术上的“随机”。

    【讨论】:

    • 我喜欢你的最后一种方法,尽管我认为你不能过滤属性。您必须在模型本身中添加子集列并在保存时设置它的值,如下所示:ifacethoughts.net/2009/07/14/calculated-fields-in-django
    • 将子集作为方法添加到内容模型中不足以对其进行过滤,正如您上次 sn-p 中所建议的那样。
    【解决方案3】:

    我愿意:

    import random    
    object_list = list(Content.objects.filter(foo=bar).values()[:100])
    random.shuffle(object_list)
    

    只运行一个简单的 MySQL 查询并且性能很好。

    【讨论】:

    • 这不会从数据库中返回随机记录。它选择前一百个记录并将它们洗牌。记录 101 以后没有机会被选中。
    • 我的意思是建议在 order_by('?') 上使用 shuffle 函数,它有严重的性能问题:stackoverflow.com/a/6405601/232649 对所有记录进行洗牌:shuffle(list(Content.objects.all()) )[:100]
    猜你喜欢
    • 2018-11-19
    • 2019-03-25
    • 2012-12-11
    • 1970-01-01
    • 2013-01-03
    • 1970-01-01
    • 2018-11-30
    • 2021-05-11
    相关资源
    最近更新 更多