2013-08-31 4 views
2

У меня есть коллекция документов, которые выглядят следующим образом:Как агрегировать запросы в MongoDB

{ 
    name : "tester" 
    , activity: [ 
    { 
     gear: "glasses" 
     where: "outside"  
    } 
    , { 
     gear: "hat" 
     , where: "inside" 
    } 
    , { 
     gear: "glasses" 
     , where: "car" 
    } 
    ] 
} 

Как запросить коллекцию возвращать только документы с кратному деятельности, которые содержат значение «зубчатого колеса» :"очки"?

Спасибо!

+1

Вероятно нужна раскрутка и сумма с условием. Что вы пробовали? – WiredPrairie

ответ

3

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

db.collection.find({ 
    "activity": {$elemMatch: {gear:"glasses"}}, 
    "activity.1" : {$exists: 1} 
}) 
+0

Это похоже на работу, что делает .1? Это поиск длины массива активности? Могу ли я также использовать .2, чтобы проверить, есть ли у него 2 "очки"? – justin

+0

Он проверяет наличие элемента с индексом 1 –

2

Это будет некрасиво с каркасом агрегации, но это может быть сделано:

db.collection.aggregate(
    {$match: {"activity.gear": "glasses"}}, 
    {$unwind: "$activity"}, 
    {$group: { 
    _id: {_id: "$_id", name: "$name"}, 
    _count: {$sum: {$cond: [{$eq: ["glasses", "$activity.gear"]}, 1, 0]}} 
    }}, 
    {$match: {_count: {$gt: 1}}} 
) 

При анализе выше запрос, я рекомендовал бы ходить через шаг. Начните с «$ match», «$ match» и «$ unwind». И вот один. Вы увидите, как каждый шаг работает.

Ответ не является полным документом. Если вы ищете полный документ, включите этап $project, который проходит через фиктивную активность, и восстановите полный документ на выходе.

1

Вы также можете попробовать это:

db.collection.find({ activity: { $elemMatch: { gear: "glasses" } }) 
+1

Эта логика ничем не отличается от: 'db.collection.find ({" activity.gear ":" очки "})'. –

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