Запрос MongoDB на основе количества вложенных документов - PullRequest
4 голосов
/ 16 января 2011

Предположим, у меня есть:

Order: {_id: ..., items: [...]}

Как отфильтровать заказы с номером элемента больше 5?

Ответы [ 4 ]

6 голосов
/ 16 января 2011

Вы не можете делать запросы по размеру встраиваемой коллекции, вам нужно создать поле с размером коллекции для таких нужд (документация mongo db):

Оператор $ size сопоставляет любой массив суказанное количество элементов.Следующий пример будет соответствовать объекту {a: ["foo"]}, так как этот массив имеет только один элемент:

db.things.find ({a: {$ size: 1}});

Вы не можете использовать $ size, чтобы найти диапазон размеров (например: массивы с более чем 1 элементом).Если вам нужно запросить диапазон, создайте поле дополнительного размера, которое вы увеличиваете при добавлении элементов.

5 голосов
/ 16 января 2011

Вы можете использовать оператор $ where.

> db.orders.save({Order: {items: [1,2]}})                                                    
> db.orders.save({Order: {items: [1,2,3]}})
> db.orders.find({$where:function() { if (this["Order"]["items"].length > 2) return true; }})
{ "_id" : ObjectId("4d334c9102bcfe450ce52585"), "Order" : { "items" : [ 1, 2, 3 ] } }

Два недостатка $ where в том, что он не может использовать индекс, и объект BSON должен быть преобразован в объект JavaScript, так как вы выполняетепользовательская функция JavaScript для каждого документа в коллекции.

Итак, $ where может быть очень медленным для больших коллекций.Но для специальных или редко запускаемых запросов это очень удобно.Если вам часто нужно запускать подобные запросы, следуйте рекомендациям Bugai13, так как вы можете затем индексировать ключ, в котором вы храните размер массива.

2 голосов
/ 20 января 2011

Я тоже столкнулся с этой дилеммой. Не уверен, почему он не существует в MongoDB по умолчанию. Наиболее эффективный способ - это также сохранить свойство с именем count или length или что-то, что обозначает количество элементов в массиве.

Затем вы можете проиндексировать это свойство и выполнить диапазон запросов к нему. Это сделает ваши запросы простыми и быстрыми.

Просто убедитесь, что ваше приложение поддерживает синхронизацию.

0 голосов
/ 30 мая 2019

Чтобы увидеть, если длина больше 5, вы можете проверить, существует ли 6-й элемент:

db.orders.find({"items.6": {$exists: true}})

Это намного эффективнее, чем использование $where.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...