2015-02-26 2 views
1

Я хочу запустить запрос для выбора определенных документов. Затем в каждом документе откройте массив вспомогательных документов и запустите запрос для фильтрации этих вспомогательных документов.Mongodb как я могу запросить подмножество массива для определенного документа

Пример:

{ 
    "_id" : ObjectID(23412351346435), 
    "list" : [ 
    {date: ISODate(2015-01-12T00:00:00.000Z), name: "Jan 12"}, 
    {date: ISODate(2015-01-13T00:00:00.000Z), name: "Jan 13"}, 
    {date: ISODate(2015-01-14T00:00:00.000Z), name: "Jan 14"} 
    ] 
} 

Я предполагаю, что я могу сделать что-то с aggregate функции Mongo в. Мне удалось сопоставить документы, которые я хочу, но как я могу получить дополнительный запрос, идущий по массиву? Я попытался использовать $elemMatch, но это возвращает только первый элемент в массиве, который соответствует диапазону дат.

Чтобы быть ясным, когда я запрашиваю ObjectID(23412351346435) и диапазон дат 2015-01-12 по 2015-01-13 Я хочу, чтобы он возвращал это;

{ 
    "_id" : ObjectID(23412351346435), 
    "list" : [ 
     {date: ISODate(2015-01-12T00:00:00.000Z), name: "Jan 12"}, 
     {date: ISODate(2015-01-13T00:00:00.000Z), name: "Jan 13"} 
    ] 
} 
+0

смог получить результаты, которые вы искали Были ли вы? –

ответ

0

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

  1. Match документы, которые вы хотите. (Я сделал это здесь _id).
  2. Unwindlist массив.
  3. Сопоставьте даты, которые вы ищете, используя запрос диапазона.
  4. Group документы назад _id.

Ваш запрос должен выглядеть следующим образом:

db.collection.aggregate([ 
    { "$match": { "_id": ObjectId("54ef8b0acfb269d664de0b48")} }, 
    { "$unwind": "$list" }, 
    { "$match": { 
     "list.date": { $gte: ISODate("2015-01-12T00:00:00.000Z"), 
         $lte: ISODate("2015-01-13T00:00:00.000Z") 
     } 
    }}, 
    { "$group": { 
     "_id": "$_id", 
     "list": { "$push": { "date": "$list.date", "name": "$list.name" }} 
    }} 
]); 
+0

Ahh, группа разматывания + - это то, что я искал. Не думал использовать группу, чтобы вернуть их вместе. – dubRun

+0

Удивительный! Сообщите мне, если это сработает для вас. –

1

Вы можете использовать оператор $unwind. Он позволяет брать массив в документе и клонировать этот документ с каждым из элементов массива. Затем вы можете сопоставлять поля. Если необходимо, вы можете использовать $ group для резервного копирования документа.

[ 
    {$match:{...}}, 
    {$unwind:"myfield"}, 
    {$match:{"myfield.name":"Jan 12"}}, 
    {$group:{ _id:"$id", "myfield":{$push:"$myfield"} }} 
] 

Обратите внимание, что $ размотки медленно для больших наборов документов и комбинаторная для нескольких массивов. Это единственный вариант, который у вас действительно есть для Mongo 2.4.x. Возможно, вам лучше обслуживать путем переупорядочения ваших данных, чтобы у вас не было массивов.

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