Mongoose删除(pull)数组中的文档时,无法使用ObjectID。

37

我有以下的mongoose模式:

user = {
    "userId" : "myId",
    "connections":
    [{
        "dateConnectedUnix": 1334567891,
        "isActive": true
    }, {
        "dateConnectedUnix": 1334567893,
        "isActive": false
    }]
}

我想删除connections数组中的第二个元素,以获得以下结果:

user = {
    "userId" : "myId",
    "connections": 
    [{
        "dateConnectedUnix": 1334567893,
        "isActive": false
    }]
}
以下代码按预期运行:

以下代码按预期工作:

userAccounts.update(
    { 'connections.isActive': false }, 
    { $pull: { 'connections.isActive':false }}, 
    function (err, val) {
        console.log(val)
    }
);

但是,我需要根据ObjectId删除。以下的操作不起作用:

userAccounts.update(
    { 'connections._id': '1234-someId-6789' }, 
    { $pull: { 'connections._id': '1234-someId-6789' } },
    function (err, val) {
        console.log(val)
    }
);

有任何建议吗?我已经在屏幕前(即Google,Stackoverflow等)苦苦思索了几个小时,但没有任何进展。


有人可以帮我吗:https://stackoverflow.com/questions/49124014/removing-object-with-objectid-from-array-in-mongoose-mongodb/49126608#49126608 问题类似 :( - Ckusuma
9个回答

55

看起来上面的代码不起作用。甚至对于我给出的第一个示例也不应该起作用。

最后,我在这个答案的支持下完成了我的工作:MongoDB,从数组中删除对象

这是我的可行代码:

userAccounts.update( 
    { userId: usr.userId },
    {
        $pull: {
            connections: { _id : connId }
        }
    },
    { safe: true },
    function removeConnectionsCB(err, obj) {
        // ...
    }
);

2
connIdÕÆīusr.userIdµś»ÕÉ”µś»ObjectIdńÜäÕ«×õŠŗ’╝¤ - Jürgen Paul
我以为 safe: true 是默认设置的? - Will Brickner

22

我有一个文件,如下图:

enter image description here

我需要从地址数组中删除地址。

在互联网上搜索了很多后,我找到了解决方案。

Customer.findOneAndUpdate(query, {$pull: {address: addressId}}, (err, data) => {
    if (err) {
        return res.status(500).json({ error: 'error in deleting address' });
    }
    res.json(data);   
});

完全相同的问题,但对我不起作用。这是 MongoDB 的哪个版本? - Julio Ojeda
你的查询和路由URL是什么?如果其中包含addressId动态参数会怎样? - NoobCoder
你应该像这样执行更新查询:Customer.findOneAndUpdate(query, {$pull: {address: mongoose.Type.ObjectId(addressId)}}, (err, data) => { if (err) { return res.status(500).json({ error: '删除地址时出错' }); } res.json(data); }); - Dinuka Salwathura

11
user: {
 _id: ObjectId('5ccf3fa47a8f8b12b0dce204'),
 name: 'Test',
 posts: [
  ObjectId("5cd07ee05c08f51af8d23b64"),
  ObjectId("5cd07ee05c08f51af8d23c52")
 ]
}

从posts数组中删除单个帖子

user.posts.pull("5cd07ee05c08f51af8d23b64"); user.save();


最好的选择,特别是在更新已找到的文档时。 - 5ervant - techintel.github.io
同样的事情对我也不起作用,没有错误提示,只是不起作用,有什么线索吗? - ezio4df

10
使用 ObjectId 进行更新时,应该使用 ObjectId 对象而不是字符串表示形式:
var ObjectId = require('mongoose').Types.ObjectId;

userAccounts.update(
    { 'connections._id': new ObjectId('1234-someId-6789') }, 
    { $pull: { 'connections._id': new ObjectId('1234-someId-6789') } }, 
    function (err,val) {
        console.log(val)
    }
);

感谢您的回答。从技术上讲,我认为您是正确的。但实际上,我是在使用有效的ObjectId JSON格式引用我的代码。我已经发布了自己的答案。 - psiphi75
2
我认为你的代码有点误导性。例如,在第3行中,你写了connections_.id,而实际上原始问题清楚地显示connections是一个对象数组,没有附加_id属性。 - AllJs

7

使用findByIdAndUpdate从数组中删除元素

你可以在mongoose 5.4.x及以上版本中完成此操作。

const result = await User.findByIdAndUpdate(user_id, {
    $pull: {
        someArrayName: { _id: array_item_id }
    }
}, { new: true });

根据提供的属性_id值,将从数组中删除该项。


3
如果你正在使用 mongoose,就不需要再使用MongoDB相关内容了,因为我们一开始就是在使用mongoose,对吧?
userAccounts.connections.pull({ _id: '1234-someId-6789'});
await userAccounts.save();

1

mongoose: 4.11.11
对我有用的语法如下:

const removeTansactionFromUser = (userId, connectionId) => {
    return User.findByIdAndUpdate(userId, { $pull: { "connections": connectionId} }, {'new': true} );
};

Mongoose支持字符串格式或ObjectId格式的id。
提示: new ObjectId(stringId) 可以将字符串转换为ObjectId。

1
在mongoose 5.8.11中,这个$pull: { ... }对我来说没有起作用,目前还不确定原因。所以我在控制器中通过以下方式解决了这个问题:
exports.removePost = async (req, res, next) => {
  const postId = req.params.postId;
  try {
    const foundPost = await Post.findById(postId);
    const foundUser = await User.findById(req.userId);
    if (!foundPost || !foundUser) {
      const err = new Error(
        'Could not find post / user.',
      );
      err.statusCode = 404;
      throw err;
    }
    // delete post from posts collection:
    await Post.findByIdAndRemove(postId);
    // also delete that post from posts array of id's in user's collection:
    foundUser.posts.pull({ _id: postId });
    await foundUser.save();
    res.status(200).json({ message: 'Deleted post.' });
  } catch (err) {
    // ...
  }
};

0
注意:如果您使用带有语法的拉取方法:$pull: {propertyId: _id},其中_id可以从文档中找到,请确保_id是字符串类型,如果不使用toString()方法将其转换为字符串类型。让我们来检查一下!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接