从嵌套数组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中删除元素的主要内容,如果未能解决你的问题,请参考以下文章