я предполагаю, что «учащиеся» и «учителя» являются одновременно массивами и расположены под общим поддокументом заголовок следующим образом:
{
"_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
.
Так что «наборы» - это ваш самый быстрый вариант, когда он доступен или недоступен или не уникален. Вы можете использовать более позднюю технику, чтобы объединить их в один список.