2010-08-17 4 views
33
myqueryset = Content.objects.filter(random 100) 

답변

61
Content.objects.all().order_by('?')[:100] 

order_by docs을 참조하십시오. 또한이 방법이 잘 확장되지 않는다는 사실을 알고 있어야합니다 (사실, 실제로는 너무 나쁘게 조정됩니다). 많은 양의 데이터가있을 때 임의 선택을 처리하는 더 좋은 방법은 this SO answer을 참조하십시오.

+5

그리고 all ​​()은 중복되지만 기억하지 않습니다. – Tom

+0

이것은 대단합니다! 디버깅을 통해 좋은 쿼리를 생성하고 20 개의 요소 만 잡아서 1 개의 쿼리를 사용하고 ORDER BY RAND()를 무작위로 사용하는 것으로 나타났습니다. 맙소사, 환상적입니다. –

9

두 번 이상이 작업을 수행하려면 데이터베이스에이를 설계해야합니다.

한 번 해보신다면 엄청난 벌금을 내셔도됩니다. 정말 좋은 무작위 속성을 사용하면 정확히 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) 

빠른이며 재현합니다. 부분 집합은 기술적으로 "임의"가 아닌 "임의적"입니다.

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

만 실행 단일 간단한 MySQL의 쿼리 성능에 좋다 :

+0

성능에 좋은 점 –

+0

속성을 필터링 할 수 있다고는 생각하지 않지만 마지막 접근 방식을 좋아합니다. 모델 자체에 부분 집합 열을 추가하고 다음과 같이 값을 저장하도록 설정해야합니다. http://ifacethoughts.net/2009/07/14/calculated-fields-in-django/ – jesal

+0

메소드로 하위 집합 추가 마지막 스 니펫에서 제안한 것처럼 Content 모델로 필터링하는 것만으로는 필터링 할 수 없습니다. –

1

내가 할.

+1

데이터베이스에서 임의의 레코드를 반환하지 않습니다. 처음 100 개의 레코드를 골라 뒤섞습니다. 101 번 이후의 레코드는 선택 될 기회가 없습니다. – Blair

+0

나는 심각한 성능 문제가있는 order_by ('?')에 대한 shuffle 함수의 사용을 제안하려고 한 것입니다 : http://stackoverflow.com/a/6405601/232649 모든 레코드를 셔플 링하려면 : shuffle (list (Content.objects .all())) [: 100] – Pratyush

관련 문제