javascript - Mongoose 查找/更新子文档

我对文档文件夹有以下架构:

var permissionSchema = new Schema({
    role: { type: String },
    create_folders: { type: Boolean },
    create_contents: { type: Boolean }
});

var folderSchema = new Schema({
    name: { type: string },
    permissions: [ permissionSchema ]
});

因此,对于每个页面,我可以拥有许多权限。在我的 CMS 中有一个面板,我在其中列出了所有文件夹及其权限。管理员可以编辑单个权限并保存。

我可以轻松地保存整个 文件夹 文档及其权限数组,其中只修改了一个权限。但我不想保存所有文档(真正的架构有更多字段)所以我这样做了:

savePermission: function (folderId, permission, callback) {
    Folder.findOne({ _id: folderId }, function (err, data) {
        var perm = _.findWhere(data.permissions, { _id: permission._id });                

        _.extend(perm, permission);

        data.markModified("permissions");
        data.save(callback);
    });
}

但问题是 perm 总是 undefined!我尝试以这种方式“静态”获取权限:

var perm = data.permissions[0];

而且效果很好,所以问题是下划线库无法查询权限数组。所以我想有一个更好的(和工作)方法来获取获取的文档的子文档。

有什么想法吗?

P.S.:我解决了使用“for”循环检查 data.permission 数组中的每个项目并检查 data.permissions[i]._id == permission._id 但我想要一个更智能的解决方案,我知道有一个!

最佳答案

正如您所注意到的, Mongoose 中的默认设置是,当您将数据“嵌入”这样的数组中时,您会为每个数组条目获得一个 _id 值,作为它自己的子文档属性的一部分.您实际上可以使用此值来确定要更新的项目的索引。执行此操作的 MongoDB 方法是 positional $运算符变量,它保存数组中“匹配”的位置:

Folder.findOneAndUpdate(
    { "_id": folderId, "permissions._id": permission._id },
    { 
        "$set": {
            "permissions.$": permission
        }
    },
    function(err,doc) {

    }
);

那个 .findOneAndUpdate()方法将返回修改后的文档,或者如果您不需要返回的文档,您可以使用 .update() 作为方法。主要部分是“匹配”要更新的数组元素和“识别”与 positional $ 匹配的元素。如前所述。

那么您当然使用的是 $set运算符,以便 only 您指定的元素实际上“通过网络”发送到服务器。您可以通过 "dot notation" 进一步了解。并且只需指定您实际要更新的元素。如:

Folder.findOneAndUpdate(
    { "_id": folderId, "permissions._id": permission._id },
    { 
        "$set": {
            "permissions.$.role": permission.role
        }
    },
    function(err,doc) {

    }
);

这就是 MongoDB 提供的灵 active ,您可以非常“有针对性”地实际更新文档。

然而,它的作用是“绕过”您可能已经内置到“mongoose”架构中的任何逻辑,例如“验证”或其他“预保存 Hook ”。那是因为“最佳”方式是 MongoDB 的“功能”以及它的设计方式。 Mongoose 本身试图成为这个逻辑的“方便”包装器。但是,如果您准备自己进行一些控制,则可以以最优化的方式进行更新。

因此,在可能的情况下,请保持您的数据“嵌入”并且不要使用引用模型。它允许在您无需担心并发性的简单更新中对“父”和“子”项进行原子更新。可能是您应该首先选择 MongoDB 的原因之一。

https://stackoverflow.com/questions/26156687/

相关文章:

mongodb - 何时在 MongoDB 集合上调用 ensureIndex?

mongodb - 使用 Mongoid 批量插入/更新?

mongodb - 查询 MongoDB 中的内部数组大小

python - 在日期时间的月、日、年...上查询 Mongodb

json - 将json文件导入mongo的正确方法

mongodb - 如何从 MongoDB 文档中的双重嵌套数组中删除元素

mongodb - 数据库中的集合数量限制

mongodb - 将 mongodb 数据库从本地主机迁移到远程服务器

javascript - 如何将图像文件放入 json 对象中?

python - mongodb游标id无效错误