【问题标题】:Remove element from nested array mongodb从嵌套数组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 我需要运行命令吗?

标签: node.js mongodb mongoose mongodb-query


【解决方案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)});
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-19
  • 2022-07-19
  • 1970-01-01
  • 1970-01-01
  • 2021-12-11
  • 2017-05-18
相关资源
最近更新 更多