你需要使用两个
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"}
])