【问题标题】:How to remove Object from array using mongoose如何使用猫鼬从数组中删除对象
【发布时间】:2017-03-28 02:07:04
【问题描述】:

我正在尝试使用 mongoose 从文档中的数组中删除一个对象。

架构如下:

var diveSchema = new Schema({
//irrelevant fields
    divers: [{
        user: { type: Schema.Types.ObjectId, ref: 'User', required: true },
        meetingLocation: { type: String, enum: ['carpool', 'onSite'], required: true },
        dives: Number,
        exercise: { type: Schema.Types.ObjectId, ref: 'Exercise' },
    }]
});

一个可能的条目可以是

{
    //irrelevant fields
    "divers": [
        {
            "_id": "012345678",
            "user": "123456789",
            "meetingLocation": "carpool",
            "exercise": "34567890",
        },
        {
            "_id": "012345679",
            "user": "123456780",
            "meetingLocation": "onSite",
            "exercise": "34567890",
        }
    ]
}

假设我想删除 user123456789 的条目(注意我此时不知道 _id)。

我该如何正确地做到这一点?

我尝试了以下方法:

        var diveId = "myDiveId";
        var userIdToRemove = "123456789"
        Dive.findOne({ _id: diveId }).then(function(dive) {
            dive.divers.pull({ user: userIdToRemove });
            dive.save().then(function(dive) {
                //do something smart
            });
        });

这不会导致文档发生任何变化。

我也试过了

Dive.update({ _id: diveId }, { "$pull": { "divers": { "diver._id": new ObjectId(userIdToRemove) } } }, { safe: true }, function(err, obj) {
    //do something smart
});

这样我得到的结果是整个 divers 数组在给定的潜水中被清空了。

【问题讨论】:

    标签: arrays node.js mongodb mongoose


    【解决方案1】:

    这个呢?

    Dive.update({ _id: diveId }, { "$pull": { "divers": { "user": userIdToRemove } }}, { safe: true, multi:true }, function(err, obj) {
        //do something smart
    });
    

    【讨论】:

    • 这似乎有效!谢谢,但你能解释一下我做错了什么吗,因为我之前确实尝试过只使用user,但我没有添加multi 部分
    • 当您有查询单个文档{ _id: diveId } 的更新操作时,此选项{ safe: true, multi:true } 有何帮助?
    • @chridam ,你是对的,对于单个文档和 $pull 使用 multi:true 会有点过头了,但老实说,我遇到了一些驱动程序一旦执行就停止执行如果您不提供 multi 作为 true,则只需一项操作(不是文档)。例如,如果您在数组中调用 $set,驱动程序只会为某个驱动程序设置数组的第一个元素。这就是我使用它的原因。你可以避免它。
    • @Sonaryr 如果您确实尝试过同样的查询,也许我之前的评论中提到了它不起作用的原因,这一切基本上都归结为您的驱动程序是如何实现操作的。
    【解决方案2】:

    我用这个代码解决了这个问题-

     await Album.findOneAndUpdate(
        { _id: albumId },
        { $pull: { images: { _id: imageId } } },
        { safe: true, multi: false }
      );
      return res.status(200).json({ message: "Album Deleted Successfully" });
    

    【讨论】:

      【解决方案3】:

      试试这个

      Dive.update({ _id: diveId },{"$pull": { "drivers": {"user": "123456789"}}})

      【讨论】:

      • 与上述相同的答案。
      【解决方案4】:

      试试这个异步代码

      var diveId = "myDiveId";
      var userIdToRemove = "123456789"
      const dive=await Dive.findOne({ _id: diveId })
      await dive.divers.pull({ user: userIdToRemove });
      await dive.save();
      

      【讨论】:

      • 欢迎来到 Stack Overflow!如果您解释了它的工作原理/原因和/或为什么此解决方案比已经存在一段时间的现有答案更好,您的答案可能对其他人更有帮助:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-03
      • 1970-01-01
      • 2021-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-23
      相关资源
      最近更新 更多