我有一组文档,它们周围可以有各种 READ 隐私设置:
- 它们可以完成公开(任何注册用户)可以查看它们
- 只有关注您的人才能查看它们(此“关注者”数组存储在每个用户的文档中)
- 它们也可以对发布文档的人保密。
- 他们可以具有自定义隐私,允许您命名可以查看文档的个人用户。此外,您可以允许用户组也查看文档(例如,可能有一个名为“Sample Group”的组,其中有 20 个用户。您可以允许该组查看磁贴。)
我不知道如何在 MongoDB 中有效地实现这个模式,并且希望深入了解实现这个模式的最佳实践。
我们已经完成了几个具有多个访问级别和 mongoose 的项目,这是迄今为止我们最喜欢的方法:
var ACCESS_MODES = 'public followers private explicit'.split(' ');
var projectSchema = new Schema({
access: { type: String, enum: ACCESS_MODES, required: true, default: 'public' },
owner: { type: Schema.Types.ObjectId, ref: 'User' }]
});
然后我们通常会在模式上实现一些自定义访问方法,例如:
projectSchema.statics.getByIdFor = function(user, id, done) {
this.findOne({ _id: id }).populate('owner').exec(onFound);
function onFound(err, project) {
// now check 'user' against the project's access method:
if (project.access === 'public') return done(undefined, project);
if (project.access === 'private') {
// ...etc, handle the logic for access at different levels
}
// finally, they didn't get access
done(new Error('no permission to access this project'));
}
};
所以你现在可以做这样的事情并且知道它是安全的:
ProjectModel.findByIdFor(loggedinUser, req.params.projectId, onFound);
要查找用户有权访问的所有项目:
projectSchema.statics.getForUser = function(user, done) {
var accessible = [];
this.find({ access: 'public' }).exec(onPublic);
this.find({ access: 'followers' }).populate('owner').exec(onFollowers);
this.find({ access: 'private', owner: user }).exec(onPrivate);
this.find({ access: 'explicit' }).populate('owner').exec(onExplicit);
// add onPublic/Followers/Private/Explicit to accessible where user is in the correct list
};
由于您没有指定您正在使用的驱动程序(尽管标记为 Javascript,所以也许您正在使用猫鼬?)我将尝试使用伪代码/结构来回答这个问题。
我认为您的document
收藏可能看起来像这样:
{
_id,
title,
owner, //ref to User collection?
access, //'public', 'followers' etc...
permissions[]
}
Permission
可能看起来像:
{
// one or the other
user_id
group_id
}
现在,棘手的部分是生成一个给定用户可查看的文档列表。
接近这个
function findDocumentsViewableByUser(userID){
var followedBy = //populate a list of userIDs that FOLLOW the passed in userID
var groupIDs = //populate a list of groupIDs this user is a member of
// all documents where access = 'public'
// all documents where access = 'followers' AND owner_id is in followedBy
// all documents where access = 'custom'
// and permissions.user_id = userID OR groupIDs contains permissions.groupID
}
根据您的 User 和 Group 类型文档的结构,上述 findDocumentsViewableByUser 中的查询将显着减少。
您可能最好也为此使用聚合框架。