我目前正在使用聚合操作符来返回包含一个嵌入(子)文档数组的文档。我想重命名数组的字段名,并在数组的嵌入文档中重命名字段名。
例如,对于投影,我希望将数组从“朋友”重命名为“好友”,并将嵌入文档中的字段从“名称”重命名为"nickName“。我可以在聚合操作中这样做吗?如果是的话,如何做到?
下面是源代码文档的一个示例:
[
{
_id: ObjectID,
name: 'Matthew',
friends: [
{name: 'Slim', age: '32'},
{name: 'buba', age: '36'}
]
}
]结果应该是这样的:
[
{
_id: ObjectID,
name: 'Matthew',
buddies: [
{nickName: 'Chris', age: '32'},
{nickName: 'Jim', age: '36'}
]
}
]谢谢你提前帮忙。
发布于 2014-09-10 04:44:09
有几种方法可以做到这一点,但这主要取决于您的MongoDB版本。2.6及以上的最新版本支持$map操作符,您可以在$project中使用该运算符来执行您想做的事情:
db.friend.aggregate([
{ "$project": {
"name": 1,
"buddies": {
"$map": {
"input": "$friends",
"as": "el",
"in": {
"nickName": "$$el.name",
"age": "$$el.age"
}
}
}
}}
])在以前的版本中,您将使用$unwind处理数组元素,并通过$group进行重新构造。
db.collection.aggregate([
{ "$unwind": "$friends" },
{ "$group": {
"_id": "$_id",
"name": { "$first": "$name" },
"buddies": {
"$push": {
"nickName": "$friends.name",
"age": "$friends.age"
}
}
}}
])由于第一种形式更高效,因为您没有去规范化数组内容并在管道中生成更多要处理的文档。
发布于 2014-09-10 05:01:28
我想我想出了下面的聚合查询。如果有更好的方法,我会感兴趣的。
db.friends.aggregate([
{ $unwind: '$friends'},
{ $project: {
_id: 1,
name: 1,
buddy: {
nickName: '$friends.name',
age: '$friends.age',
}
}},
{ $group: {
_id: '$_id',
name: {'$first': '$name'},
buddies: {"$push": "$buddy"}
}}
]);下面我描述了每个操作符($unwind,$project,$group)的响应
$unwind会返回这样的东西。它将每个嵌入的文档分解为自己的文档。所以,我们有一个文档和两个朋友子文档,现在我们有两个文档。这两个文档将具有相同的id和name字段,但朋友子文档将不同:
{
"_id" : ObjectId("539c80d43cb9fe99d183a5f7"),
"name" : "Matthew",
"friends" : {"name" : "slim", "age" : "32"}
}, {
"_id" : : ObjectId("539c80d43cb9fe99d183a5f7"),,
"name" : "Matthew",
"friends" : {"name" : "buba", "age" : "36"}
}$project会返回这样的东西。在这里,我创建了一个名为巴迪的新嵌入文档,并注意到我将"$friends.name“分配给"nickName":
{
"_id" : ObjectId("539c80d43cb9fe99d183a5f7"),
"name" : "Matthew",
"buddy" : {"nickName" : "slim","age" : "32"}
}, {
"_id" : : ObjectId("539c80d43cb9fe99d183a5f7"),,
"name" : "Matthew",
"friends" : {"nickName" : "buba","age" : "36"}
}然后$group会做这样的事情。在这里,我只是将所有内容重新组合在一起,但是将数组名称设置为“友人”:
{
"_id" : ObjectId("539c80d43cb9fe99d183a5f7"),
"name" : "Matthew",
"buddies" : [
{"nickName" : "slim","age" : "32"},
{"nickName" : "buba","age" : "36"}
]
}这似乎是可行的,但是如果朋友数组有重复的,这个过程将删除重复的。这是可以解决的,如果有一个独特的身份为每个朋友。
https://stackoverflow.com/questions/25756926
复制相似问题