MongoDB,将对象数组更改为包含其 ObjectId 的字符串数组

Posted

技术标签:

【中文标题】MongoDB,将对象数组更改为包含其 ObjectId 的字符串数组【英文标题】:MongoDB, change array of objects to an array of strings containing their ObjectId 【发布时间】:2020-11-13 06:17:08 【问题描述】:

我有一个充满包含信息的对象的数据库,以及其他对象数组。我想将内部数组更改为仅将每个索引作为 ObjectId 类型以及它们各自的 ObjectId 的数组

我稍后在程序中使用 mongoose 填充函数来检索此信息。所以引用只需要 ObjectId。

job  
    _id: 1,
    name: "name",
    parts: [ 
         _id: ObjectId("5c790ce7d3dc8d00ccc2688c"), name: "name",
         _id: ObjectId("5c790ce7d3dc8d00ccc2688b"), name: "name",
         _id: ObjectId("5c790ce7d3dc8d00ccc2688a"), name: "name",
    ]

想要的结果

job 
    _id: 1,
    name: "name",
    parts: [
        ObjectId("5c790ce7d3dc8d00ccc2688c"),
        ObjectId("5c790ce7d3dc8d00ccc2688b"),
        ObjectId("5c790ce7d3dc8d00ccc2688a")
    ]

我从命令行尝试了一些 mongoDB 查询,但它们都没有给出我需要的结果。这个没有错误,但似乎没有任何改变。

db.jobs.update(
    ,
    
        $set: "parts.$[element]": "element._id"
    ,
    
        multi: true,
        arrayFilters: [ "element":  ]
    
)

我不确定这是否可能仅使用 mongo shell。

【问题讨论】:

【参考方案1】:

正如@Tom Slabbaert 在另一个answer 中提到的,如果您想在一个操作中批量更新文档,则必须使用v4.2 中可用的updates with aggregation pipelines。

作为使用$map 的替代方法,如果您只希望顶层有一个值并且可以使用点表示法访问该值。您可以简单地将$set 与点符号一起使用。

db.jobs.updateMany(, 
  $set:  parts: "$parts._id" 
)

【讨论】:

【参考方案2】:

Mongo v4.2 引入了pipelined updates 这允许在更新中使用聚合运算符,更重要的是使用它自己的值更新文档。这就是你想要达到的目标。

db.jobs.updateMany(
    ,
    [
        
            '$set': 
                'parts': 
                    '$map': 
                        'input': '$parts',
                        'as': 'part',
                        'in': '$$part._id'
                    
                
            
        
    ]);

不幸的是,这对于早期的 Mongo 版本是不可能的。具体来说,$arrayFilters 允许您过滤数组,但在新的更新语法之前再次访问更新中的自己的值是不可能的。

您必须遍历所有文档并在代码中一一进行更新。

【讨论】:

效果很好,谢谢!也不适合未来的读者,你不能在 Robo3t 中执行这个,你需要在 mongo shell 中

以上是关于MongoDB,将对象数组更改为包含其 ObjectId 的字符串数组的主要内容,如果未能解决你的问题,请参考以下文章

如何将用逗号分隔的纯文本更改为节点中的数组? [复制]

JS 遍历对象数组并将值更改为匹配的键并创建一个包含对象数组 [0] 中的键的新对象

数组到 NSOrderedSet 将列表的大小更改为 1

如何将当前数组格式更改为对象数组格式?

使用 Php 将对象更改为数组 [重复]

将对象数组中的正数更改为负数