2014-09-18 2 views
0

меня агрегирования этап трубопровода:Выбор всех объектов из сложной модели

$project: { 
    'school': { 
     'id': '$_id', 
     'name': '$name', 
     'manager': '$manager' 
    }, 
    'students': '$groups.students', 
    'teachers': '$groups.teachers' 
} 

нужно что-то вроде этого:

{ 
    'users': // manager + students + teachers 
} 

Пробовал:

{ 
    'users': { 
     $push: { 
      $each: ['$school.manager', '$students', '$teachers'] 
     } 
    } 
} 

ответ

0

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

{ 
    "_id": 123, 
    "name": "This school", 
    "manager": "Bill" 
    "groups": { 
     "teachers": ["Ted"], 
     "students": ["Missy"] 
    } 
} 

Так что для того, чтобы получить все те, в единственном массиве, такие как «пользователи», то это зависит от версии MongoDB и «уникальности» данных. Для истинных «множеств» и где у вас есть MongoDB 2.6 или более доступны, есть оператор $setUnion, хотя и с дополнительным уровнем $group, чтобы сделать «менеджер» и массив:

db.collection.aggregate([ 
    { "$group": { 
     "_id": { "_id": "$_id", "name": "$name" }, 
     "manager": { "$push": "$manager" }, 
     "groups": { "$first": "$groups" } 
    }}, 
    { "$project": { 
     "users": { 
      "$setUnion": [ "$manager", "$groups.teachers", "$groups.students" ] 
     } 
    }} 
]) 

Или иначе, где этот оператор не доступен или есть «уникальные» проблемы, то есть этот способ справиться с «объединением»:

db.collection.aggregate([ 
    { "$group": { 
     "_id": { "_id": "_id", "name": "$name" }, 
     "manager": { "$push": "$manager" }, 
     "teachers": { "$first": "$groups.teachers" }, 
     "students": { "$first": "$groups.students" }, 
     "type": { "$first": { "$const": ["M","T","S"] } } 
    }}, 
    { "$unwind": "$type" }, 
    { "$project": { 
     "users": { 
      "$cond": [ 
       { "$eq": [ "$type", "M" ] }, 
       "$manager", 
       { "$cond": [ 
        { "$eq": [ "$type", "T" ] }, 
        "$teachers", 
        "$students" 
       ]} 
      ] 
     } 
    }}, 
    { "$unwind": "$users" }, 
    { "$group": { 
     "_id": "$_id", 
     "users": { "$push": "$users" } 
    }} 
]) 

Это по существу «метка» каждое поле с помощью «типа», для которого этого документ копируется в трубопроводе. Затем помещается в одно поле «пользователи», в зависимости от типа «тип». Затем один массив из полученных трех документов из каждого оригинала может быть безопасно «размотан» и объединен в окончательную операцию $group.

Так что «наборы» - это ваш самый быстрый вариант, когда он доступен или недоступен или не уникален. Вы можете использовать более позднюю технику, чтобы объединить их в один список.

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