从嵌套数组mongodb中删除元素

Posted

技术标签:

【中文标题】从嵌套数组mongodb中删除元素【英文标题】:Remove element from nested array mongodb 【发布时间】:2019-01-25 17:39:47 【问题描述】:

我有以下文档,它有两个数组,一个在另一个里面, 附件数组中的附件数组和文件数组。 我想使用这个元素 _id 删除文件数组中的一个元素。但它不适合我,我尝试了这段代码,它返回 n: 144, nModified: 0, ok: 1

   Invoice.update(, 
        $pull: 
            "attachment":
            
                "files":
                
                    $elemMatch:
                         _id: ObjectId("5b7937014b2a961d082de9bf") 
                
            
        
    ,  multi: true )
        .then(result => 
            console.log("delete", result);


        );

这就是文档的样子

【问题讨论】:

@AnthonyWinzlet 谢谢,但帖子不同,我有 2 个数组,我想删除第一个数组中存在的第二个数组中的元素。 试试Invoice.update( , "$pull": "attachment.$[].files":_id:ObjectId("5b7969ac8fb15f3e5c8e844e") , "multi": true , function (err, result) console.log(result); ); ok: 0, n: 0, nModified: 0 MongoError: cannot use the part (attachment of attachment.$[].files) 遍历元素 (attachment: [] ) 你的 mongo 服务器版本是多少?你需要3.6。此外,您可能需要从 shell db.adminCommand( setFeatureCompatibilityVersion: 3.6 or 4.0 depending on your version ) 运行管理命令 MongoDB shell 版本 v3.4.13 连接到:mongodb://127.0.0.1:27017 MongoDB 服务器版本:3.4.13 我需要运行命令吗? 【参考方案1】:

适用于 3.6 之前的 Mongodb 版本

这里只有一个嵌套级别,因此您可以简单地使用 $ 位置运算符。

Invoice.update(
   "attachment.files._id": mongoose.Types.ObjectId("5b7937014b2a961d082de9bf") ,
   "$pull":  "attachment.$.files":  "_id": mongoose.Types.ObjectId("5b7937014b2a961d082de9bf") ,
   "multi": true 
)

适用于 Mongodb 3.6 及以上版本

如果您想更新attachement 数组中的多个元素,则可以使用$[] all 位置运算符。

const mongoose = require("mongoose")

Invoice.update(
   "attachment.files._id": mongoose.Types.ObjectId("5b7937014b2a961d082de9bf") ,
   "$pull":  "attachment.$[].files":  "_id": mongoose.Types.ObjectId("5b7937014b2a961d082de9bf") ,
   "multi": true 
)

如果您想更新attachment 数组中的单个元素,那么您可以使用$[<identifier>] 来标识与arrayFilters 条件匹配的数组元素。

假设您只想更新attachment 中的一个元素,其中_id 等于ObjectId(5b7934f54b2a961d081de9ab)

Invoice.update(
   "attachment.files._id": mongoose.Types.ObjectId("5b7937014b2a961d082de9bf") ,
   "$pull":  "attachment.$[item].files":  "_id": mongoose.Types.ObjectId("5b7937014b2a961d082de9bf")   ,
   "arrayFilters": [ "item._id": mongoose.Types.ObjectId("5b7934f54b2a961d081de9ab") ], "multi": true 
)

【讨论】:

@Winzlet 它不起作用..我得到了这个 ok: 0, n: 0, nModified: 0 您需要将您的 id 转换为对象 id...就像我在上面所做的那样 我也喜欢这个,同样的事情。 const mongoose = require('mongoose');常量 ObjectId = mongoose.Types.ObjectId; Invoice.update( "attachment.files._id": ObjectId("5b7969ac8fb15f3e5c8e844e") , "$pull": "attachment.$[].files.$[]._id": ObjectId("5b7969ac8fb15f3e5c8e844e") , "multi": true , function (err, result) console.log(result); ); @AhmadKhalaf 我已经更新了答案...请看一下 我更新到 3.6,正如 Veeram 所说,使用相同的代码,你们都提供了完美的工作^^谢谢【参考方案2】:

您可以在 3.6 版本中尝试以下更新查询。

Invoice.update( 
 , 
 "$pull":"attachment.$[].files":_id:ObjectId("5b7969ac8fb15f3e5c8e844e"), 
 "multi": true, function (err, result) console.log(result);
);

如果您是从旧版本升级,请使用db.adminCommand( setFeatureCompatibilityVersion: 3.6 or 4.0 depending on your version )

【讨论】:

如果我想使用 id 找到这个文件怎么办?我试图这样做,但它不起作用,Invoice.find( "attachment.$[].files": _id: ObjectId(fileId) , function (err, result) console.log("** ", 结果) ); 试试Invoice.find( "attachment.files": _id: ObjectId(fileId) , function (err, result) console.log("**", result) ); 不,它没有工作它返回空数组,我试过这个并且它工作但我不确定这是否是最好的方法 Invoice.findOne( "attachment.files._id" : ObjectId(fileId) , 'attachment.files.$': 1 , 异步函数 (err, result) console.log("**",result));

以上是关于从嵌套数组mongodb中删除元素的主要内容,如果未能解决你的问题,请参考以下文章

如何从 MongoDB 文档中的双重嵌套数组中删除元素。

MongoDB,从数组中的对象中删除嵌套项

MongoDB:从数组的开头删除一定数量的元素

从MongoDb中数组的数组中删除一个元素

如何从js中的数组中删除元素[元素来自mongodb] [重复]

如何从js中的数组中删除元素[元素来自mongodb] [重复]