您需要使用两个unwind 阶段和一个group 阶段执行聚合操作。基本规则是你放松的次数与嵌套深度的水平一样多。这里嵌套的级别是 2,所以我们展开两次。
collection.aggregate([
{$unwind => "$Countries"},
{$unwind => "$Countries"},
{$group => {"_id":"$_id","Countries":{$push => "$Countries"}}}
])
第一个$unwind 阶段产生结果:
{
"_id" : ObjectId("54a32e0fc2eaf05fc77a5ea4"),
"Countries" : [
"Spain",
"France"
]
}
{
"_id" : ObjectId("54a32e4ec2eaf05fc77a5ea5"),
"Countries" : [
"Spain"
]
}
{
"_id" : ObjectId("54a32e4ec2eaf05fc77a5ea5"),
"Countries" : [
"Russia",
"Egypt"
]
}
第二个$unwind 阶段进一步扁平化Countries 数组:
{ "_id" : ObjectId("54a32e0fc2eaf05fc77a5ea4"), "Countries" : "Spain" }
{ "_id" : ObjectId("54a32e0fc2eaf05fc77a5ea4"), "Countries" : "France" }
{ "_id" : ObjectId("54a32e4ec2eaf05fc77a5ea5"), "Countries" : "Spain" }
{ "_id" : ObjectId("54a32e4ec2eaf05fc77a5ea5"), "Countries" : "Russia" }
{ "_id" : ObjectId("54a32e4ec2eaf05fc77a5ea5"), "Countries" : "Egypt" }
现在最后的$group 阶段根据_id 对记录进行分组,并将国家/地区名称累积在一个数组中。
{
"_id" : ObjectId("54a32e4ec2eaf05fc77a5ea5"),
"Countries" : [
"Spain",
"Russia",
"Egypt"
]
}
{
"_id" : ObjectId("54a32e0fc2eaf05fc77a5ea4"),
"Countries" : [
"Spain",
"France"
]
}
如果您希望在文档中保留其他字段,则需要使用$first 运算符明确指定国家/地区字段以外的字段名称(field1、field2 等)。您可以通过在$out 阶段指定集合的名称来写入/覆盖集合。
collection.aggregate([
{$unwind => "$Countries"},
{$unwind => "$Countries"},
{$group => {"_id":"$_id","Countries":{$push => "$Countries"},
"field1":{$first => "$field1"}}},
{$out => "collection"}
])
您需要明确指定字段,以免获得多余的Countries 字段。
您可以使用$$ROOT 系统变量来存储整个文档,但这会使Countries 字段变得多余。一个在doc 之外,一个在doc 内部。
collection.aggregate([
{$unwind => "$Countries"},
{$unwind => "$Countries"},
{$group => {"_id":"$_id","Countries":{$push => "$Countries"},
"doc":{$first => "$$ROOT"}}},
{$out => "collection"}
])