Запрос более 27 миллионов документов в mongodb

У нас есть 27 миллионов документов, распределенных по 3 сегментам, каждый из которых содержит примерно 9 миллионов документов. Каждый документ имеет ~ 15 проиндексированных полей. Требование состоит в том, чтобы мы могли фильтровать эти документы, используя комбинации проиндексированных полей. count() занимает не более 20 секунд для сложных запросов.

Нам также нужно извлечь конкретное поле тех документов, которые соответствуют фильтрам, используя find(). Однако иногда это занимает несколько минут, особенно если результат превышает 1 миллион документов. Это выполняется через вызов веб-службы, поэтому иногда возникает тайм-аут.

Я хочу знать, может ли добавление большего количества осколков решить проблему или есть другие способы оптимизации, которые мы можем применить.

Спасибо!


person alexishacks    schedule 30.10.2013    source источник
comment
у вас есть возможность ввести лимит и перебирать запросы по смещению? таким образом вы можете позволить монго вернуться быстрее   -  person dunn less    schedule 30.10.2013
comment
получение 1 миллиона документов за раз практически невозможно. вам нужно разбить на страницы.   -  person Mustafa Genç    schedule 30.10.2013
comment
Использует ли он индекс, когда для ответа требуются минуты? Насколько велик возвращаемый набор результатов (в МБ)?   -  person WiredPrairie    schedule 30.10.2013
comment
Запрос выполняется API Node.js. Он повторяет курсор mongodb, что может занять много времени, если есть миллион записей, соответствующих запросу. Как я могу использовать разбиение на страницы, если весь набор результатов должен быть возвращен с помощью только одного вызова API?   -  person alexishacks    schedule 31.10.2013
comment
кажется, что никто не сталкивался с этим вариантом использования раньше. :)   -  person alexishacks    schedule 12.11.2013


Ответы (2)


Добавление большего количества осколков вам не поможет, но вы можете выполнить разбивку на страницы, которая может возвращать ограниченные документы, для которых вам нужно выполнить несколько вызовов API.

ты можешь сделать вот так

db.users.find(/*condition*/).limit (10000)

db.users.find(/*condition*/).skip(10000).limit(10000)

db.users.find(/*condition*/).skip(20000).limit(10000) 
person Murugan Perumal    schedule 23.06.2017

У меня была такая же проблема в проекте с десятками миллионов записей со сложными фильтрующими запросами.

Я не знаю, достаточно ли у вас ресурсов или это возможно для вашего проекта, но я решил, что проект будет создавать новую коллекцию, содержащую результаты отчетов.

Система предоставляет и обновляет отчеты во время простоя, и большинство отчетов готовы к использованию или нуждаются в обновлении только для новых полей.

Кроме того, как уже говорилось, пейджинг является обязательным для такого рода запросов.

Если вы решите проблему с выполнением запроса, и это будет достаточно быстро, HTTP-запрос для обработки такого большого количества данных будет недостаточно быстрым для хорошего взаимодействия с пользователем.

person SalmanShariati    schedule 10.04.2021