2016-06-07 7 views
3

Существует множество способов выбора случайного документа из коллекции mongodb (как обсуждалось in this answer). Комментарии указывают, что с версией mongodb> = 3.2, тогда использование $sample в структуре агрегации является предпочтительным. Однако в коллекции со многими небольшими документами это кажется чрезвычайно медленным.

Следующий код использует mongoengine для имитации проблемы и сравнить его с «перескочить» случайного метода:

import timeit 
from random import randint 

import mongoengine as mdb 

mdb.connect("test-agg") 


class ACollection(mdb.Document): 
    name = mdb.StringField(unique=True) 

    meta = {'indexes': ['name']} 


ACollection.drop_collection() 

ACollection.objects.insert([ACollection(name="Document {}".format(n)) for n in range(50000)]) 


def agg(): 
    doc = list(ACollection.objects.aggregate({"$sample": {'size': 1}}))[0] 
    print(doc['name']) 

def skip_random(): 
    n = ACollection.objects.count() 
    doc = ACollection.objects.skip(randint(1, n)).limit(1)[0] 
    print(doc['name']) 


if __name__ == '__main__': 
    print("agg took {:2.2f}s".format(timeit.timeit(agg, number=1))) 
    print("skip_random took {:2.2f}s".format(timeit.timeit(skip_random, number=1))) 

Результат является:

Document 44551 
agg took 21.89s 
Document 25800 
skip_random took 0.01s 

Где бы я имел проблемы с производительностью mongodb в прошлом, мой ответ всегда заключался в использовании структуры агрегации, поэтому я удивлен $sample настолько медленный.

Я что-то упустил? Что это за пример, который вызывает агрегацию так долго?

+1

Какая версия MongoDB работает? Я обнаружил, что '$ sample' был очень медленным в 3.2.5, но в основном мгновенным в 3.2.7. – JohnnyHK

+0

ах, 3.2.0 - тогда это будет. да, [это] (https://jira.mongodb.org/browse/SERVER-21887?jql=text%20~%20%22%24sample%22) показывает, что это была известная ошибка. –

+0

Правильно, но я не уверен, почему для меня все еще было медленным с 3.2.5 с новой коллекцией документов 1М, как это было отмечено в 3.2.3. – JohnnyHK

ответ

2

Это результат known bug в двигателе WiredTiger в версиях mongodb < 3.2.3. Модернизация to the latest version должна решить эту проблему.

Смежные вопросы