mongoose-如何从$pull中删除元素

mongoose - how do I get the elements removed from $pull

本文关键字:删除 元素 pull mongoose-      更新时间:2023-09-26

我使用$pull来提取文档数组中的子文档。不知道这是否重要,但在我的情况下,子文档包含_id,因此它们被索引
以下是描述模式的JSON:

user: {
  _id: String,
  items: [UserItem]
}
UserItem: {
  _id: String,
  score: Number
}

现在我的问题是:我正在使用$pull从用户中删除某些UserItem

var delta = {$pull:{}};
delta.$pull.items={};
delta.$pull.items._id = {$in: ["mongoID1", "mongoID2" ...]};
User.findOneAndUpdate(query, delta, {multi: true}, function(err, data){
    //whatever...
});

我在这里得到的数据是更改后的User对象,而我希望得到的是从数组中删除的项目(卫星数据)。这可以通过一个对mongo的调用来完成吗?还是我必须执行两个调用:1个查找和1个$pull
谢谢你的帮助。

您真的无法做到这一点,或者至少在任何响应中都不会返回从数组"拉"来的"实际"元素,即使较新的WriteResponse对象可用于较新的批量操作API(这是一种前进的方式)。

真正做到这一点的唯一方法是"了解"您"打算"提取"的元素,然后将其与文档修改前的"原始"状态进行比较。基本的MongoDB .findAndModify()方法允许这样做,.findByIdAndUpdate().findOneAndUpdate()的mongoose包装器也允许这样做。

基本使用前提:

var removing = [ "MongoId1", "MongoId2" ];
Model.findOneAndUpdate(
    query,
    { "$pull": { "items._id": { "$in": removing } } },
    { "new": false },
    function(err,doc) {
        var removed = doc.items.filter(function(item) {
           return removing.indexOf(item) != -1;
        });
        if ( removed.length > 0 )
           console.log(removed);
    }
);

或者类似的东西。您基本上"扭转"了默认的mongoose .findOneAndUpdate()(与其他方法相同)行为,并在修改之前要求提供"原始"文档。如果您要求"提取"的元素存在于数组中,那么您将报告它们,或者检查/返回true或其他什么。

因此,mongoose方法与引用实现的不同之处在于,默认情况下返回"new"文档。关闭此选项,然后可以进行"比较"。

进一步注意:此处的"multi"不是有效选项。该方法根据定义修改"一个"文档。此外,您还声明数组子文档包含在_id中。默认情况下,这是由"猫鼬"完成的。但是数组中的_id值是"未索引的",除非您在该字段上专门定义了索引。唯一的默认索引是"主文档"_id