简体   繁体   English

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

[英]How to change field from subdocument a parent field in Mongoose

I am trying to export Mongo data to XLSX which requires all the data to be in the parent map but currently I have data in this format: 我正在尝试将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"
            }
        },
    }
]

Ideally, the data should be: 理想情况下,数据应为:

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

So basically what I want is to refer the data of fields of subdocuments as if those were part of parent document, like competitions = competitions.name. 因此,基本上我想要引用的是子文档字段的数据,就像子文档是父文档的一部分一样,例如Competitions = Competitions.name。

Can you please help me how can I do so using Mongoose. 您能帮助我如何使用猫鼬吗?

Thanks 谢谢

With some more aggregation trick 还有更多的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 }}
])

You can try below aggregation on your Model : 您可以在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
        }
    }
])

Since you need to dynamically evaluate your keys based on indexes you can use $map with $range to map a list of indexes into keys of a new object. 由于需要基于索引动态评估键,因此可以将$ map$ range一起使用,以将索引列表映射到新对象的键中。 Then you can use $arrayToObject to get an object from those keys and $mergeObjects with $replaceRoot to flatten this object structure. 然后,您可以使用$ arrayToObject从这些键中获取对象,并使用$ mergeObjects$ replaceRoot来展平此对象结构。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM