web-dev-qa-db-ja.com

Djangoで、データベースから100個のランダムレコードを選択するにはどうすればよいですか?

myqueryset = Content.objects.filter(random 100)
34
TIMEX
Content.objects.all().order_by('?')[:100]

order_by docs を参照してください。また、このアプローチはうまくスケーリングしないことに注意してください(実際、それは本当に、本当にひどくスケーリングします)。大量のデータがある場合にランダム選択を処理するためのより良い方法については、 this SO answer を参照してください。

67
Tom

これを複数回行う場合は、これをデータベースに設計する必要があります。

あなたが一度それをしているなら、あなたは多額のペナルティを支払う余裕があります。これにより、非常に優れたランダムプロパティで正確に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 ]

これを複数回実行する場合は、「ランダム」値を効果的にフィルタリングできるように、コンテンツに属性を追加する必要があります。たとえば、これを行うことができます。

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 )

これは速いであり、再現可能です。サブセットは、技術的に「ランダム」ではなく「任意」です。

10
S.Lott

私がやります:

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

単一の単純なMySQLクエリのみを実行し、パフォーマンスに優れています。

1
Pratyush