如何从子文档更改字段在Mongoose中的父字段

时间:2019-02-14 17:41:57

标签: javascript mongodb mongoose mongodb-query aggregation-framework

我正在尝试将Mongo数据导出到XLSX,这要求所有数据都在父地图中,但是目前我具有以下格式的数据:

[
    {
        "_id": "eatete",
        "competition": {
            "_id": "eatete"
            "name": "Some competition name"
        },
        "members": [
            {
                "_id": "eatete",
                "name": "Saad"
            },
            {
                "_id": "eatete",
                "name": "Saad2"
            }
        ],
        "leader": {
            "name": "Saad",
            "institute": {
                "_id": "eatete",
                "name": "Some institute name"
            }
        },
    }
]

理想情况下,数据应为:

[
    {
        "_id": "eatete",
        "competition": "Some competition name"
        "member0name": "Saad",
        "member1name": "Saad2",
        "leadername": "Saad",
        "institute": "Some institute name"
    }
]

因此,基本上我想要引用的是子文档字段的数据,就像子文档是父文档的一部分一样,例如Competitions = Competitions.name。

能帮我使用猫鼬吗?

谢谢

2 个答案:

答案 0 :(得分:2)

还有更多aggregation trick

db.collection.aggregate([
  { "$unwind": { "path": "$members", "includeArrayIndex": "i" }},
  { "$group": {
    "_id": "$_id",
    "competition": { "$first": "$competition.name" },
    "leadername": { "$first": "$leader.name" },
    "institute": { "$first": "$leader.institute.name" },
    "data": {
      "$push": {
        "k": { "$concat": ["members", { "$toLower": "$i" }, "name"] },
        "v": "$members.name"
      }
    }
  }},
  { "$replaceRoot": {
    "newRoot": {
      "$mergeObjects": ["$$ROOT", { "$arrayToObject": "$data" }]
    }
  }},
  { "$project": { "data": 0 }}
])

答案 1 :(得分:1)

您可以尝试在Model上进行以下汇总:

let resultt = await Model.aggregate([
    {
        $project: {
            _id: 1,
            competition: "$competition.name",
            leadername: "$leader.name",
            institute: "$leader.institute.name",
            members: {
                $map: { 
                    input: { $range: [ 0, { $size: "$members" } ] },
                    in: {
                        k: { $concat: [ "member", { $toString: "$$this" }, "name" ] },
                        v: {
                            $let: {
                                vars: { current: { $arrayElemAt: [ "$members", "$$this" ] } },
                                in: "$$current.name"
                            }
                        }
                    } 
                }
            }
        }
    },
    {
        $replaceRoot: {
            newRoot: {
                $mergeObjects: [ "$$ROOT", { $arrayToObject: "$members" } ]
            }
        }
    },
    {
        $project: {
            members: 0
        }
    }
])

由于需要基于索引动态评估键,因此可以将$map$range结合使用,以将索引列表映射到新对象的键中。然后,您可以使用$arrayToObject从这些键中获取对象,并使用$mergeObjects$replaceRoot来使该对象结构扁平化。