首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MongoDB聚合查询-从嵌入文档中返回的重命名字段

MongoDB聚合查询-从嵌入文档中返回的重命名字段
EN

Stack Overflow用户
提问于 2014-09-10 03:38:42
回答 2查看 6.9K关注 0票数 7

我目前正在使用聚合操作符来返回包含一个嵌入(子)文档数组的文档。我想重命名数组的字段名,并在数组的嵌入文档中重命名字段名。

例如,对于投影,我希望将数组从“朋友”重命名为“好友”,并将嵌入文档中的字段从“名称”重命名为"nickName“。我可以在聚合操作中这样做吗?如果是的话,如何做到?

下面是源代码文档的一个示例:

代码语言:javascript
复制
[
    {
        _id: ObjectID,
        name: 'Matthew',
        friends: [
            {name: 'Slim', age: '32'},
            {name: 'buba', age: '36'}
        ]
    }
]

结果应该是这样的:

代码语言:javascript
复制
[
    {
        _id: ObjectID,
        name: 'Matthew',
        buddies: [
            {nickName: 'Chris', age: '32'},
            {nickName: 'Jim', age: '36'}
        ]
    }
]

谢谢你提前帮忙。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-10 04:44:09

有几种方法可以做到这一点,但这主要取决于您的MongoDB版本。2.6及以上的最新版本支持$map操作符,您可以在$project中使用该运算符来执行您想做的事情:

代码语言:javascript
复制
db.friend.aggregate([
    { "$project": {
        "name": 1,
        "buddies": {
            "$map": {
                "input": "$friends",
                "as": "el",
                "in": {
                    "nickName": "$$el.name",
                    "age": "$$el.age"
                }
            }
        }
    }}
])

在以前的版本中,您将使用$unwind处理数组元素,并通过$group进行重新构造。

代码语言:javascript
复制
db.collection.aggregate([
    { "$unwind": "$friends" },
    { "$group": {
        "_id": "$_id",
        "name": { "$first": "$name" },
        "buddies": {
            "$push": {
                "nickName": "$friends.name",
                "age": "$friends.age"
            }
        }
    }}
])

由于第一种形式更高效,因为您没有去规范化数组内容并在管道中生成更多要处理的文档。

票数 10
EN

Stack Overflow用户

发布于 2014-09-10 05:01:28

我想我想出了下面的聚合查询。如果有更好的方法,我会感兴趣的。

代码语言:javascript
复制
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字段,但朋友子文档将不同:

代码语言:javascript
复制
{
    "_id" : ObjectId("539c80d43cb9fe99d183a5f7"),
    "name" : "Matthew",
    "friends" : {"name" : "slim", "age" : "32"}
}, {
    "_id" : : ObjectId("539c80d43cb9fe99d183a5f7"),,
    "name" : "Matthew",
    "friends" : {"name" : "buba", "age" : "36"}
}

$project会返回这样的东西。在这里,我创建了一个名为巴迪的新嵌入文档,并注意到我将"$friends.name“分配给"nickName":

代码语言:javascript
复制
{
    "_id" : ObjectId("539c80d43cb9fe99d183a5f7"),
    "name" : "Matthew",
    "buddy" : {"nickName" : "slim","age" : "32"}
}, {
    "_id" : : ObjectId("539c80d43cb9fe99d183a5f7"),,
    "name" : "Matthew",
    "friends" : {"nickName" : "buba","age" : "36"}
}

然后$group会做这样的事情。在这里,我只是将所有内容重新组合在一起,但是将数组名称设置为“友人”:

代码语言:javascript
复制
{
    "_id" : ObjectId("539c80d43cb9fe99d183a5f7"),
    "name" : "Matthew",
    "buddies" : [
        {"nickName" : "slim","age" : "32"},
        {"nickName" : "buba","age" : "36"}
    ]
}

这似乎是可行的,但是如果朋友数组有重复的,这个过程将删除重复的。这是可以解决的,如果有一个独特的身份为每个朋友。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25756926

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档