【问题标题】:How to change field from subdocument a parent field in Mongoose如何将子文档中的字段更改为 Mongoose 中的父字段
【发布时间】:2019-07-08 19:44:29
【问题描述】:

我正在尝试将 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。

您能帮我如何使用 Mongoose 做到这一点。

谢谢

【问题讨论】:

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


    【解决方案1】:

    还有一些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 }}
    ])
    

    【讨论】:

      【解决方案2】:

      您可以在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 来展平这个对象结构。

      【讨论】:

        猜你喜欢
        • 2019-02-26
        • 2017-04-26
        • 2014-11-15
        • 2014-09-13
        • 1970-01-01
        • 2017-03-07
        • 1970-01-01
        • 2015-04-12
        • 2017-05-28
        相关资源
        最近更新 更多