如何将子文档中的字段更改为 Mongoose 中的父字段

Posted

技术标签:

【中文标题】如何将子文档中的字段更改为 Mongoose 中的父字段【英文标题】:How to change field from subdocument a parent field in 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 做到这一点。

谢谢

【问题讨论】:

【参考方案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 来展平这个对象结构。

【讨论】:

以上是关于如何将子文档中的字段更改为 Mongoose 中的父字段的主要内容,如果未能解决你的问题,请参考以下文章

为啥默认情况下不需要 mongoose 中的所有字段?

如何将子框架中的 location.href 更改为相对路径?

Mongoose 将 _id 更改为 id

文档中的空白字段会占用 Mongoose 的空间吗?

MongoDB如何将数组中的字段类型从字符串更改为数组并保持原始值

检查用户 ID 是不是在 mongoose 文档中 - 如果是,将属性值更改为 true?