我是mongodb&的新手mongoose,我在mongoose文档中搜索的越多,我就越迷失
假设我有一个user
name
字段的值为 John ,John有两个role
s:
此role
中的每一个都有一些permissions
:
如您所见,每个role
都有重复项,如何在没有重复项的数组中获得用户 John 的权限(此示例中重复的一个是{{1} }),像这样:
['addQuestion','editQuestion','removeQuestion','viewAnswer']
这是我的架构:
addQuestion
如您所见,我在var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var deepPopulate = require('mongoose-deep-populate')(mongoose);
var UserSchema = new Schema({
name: String,
user_roles: [{
type: Schema.ObjectId,
ref: 'Role'
}]
});
var RoleSchema = new Schema({
name: String,
permissions: [
{
type: Schema.ObjectId,
ref: 'Permission'
}
]
});
var PermissionSchema = new Schema({
name: String
});
UserSchema.plugin(deepPopulate, {
whitelist: ['user_roles.permissions']
});
var User = mongoose.model('User', UserSchema),
Role = mongoose.model('Role', RoleSchema),
Permission = mongoose.model('Permission', PermissionSchema);
数组中没有权限名称,我有引用(permissions
s)。
我只有来自网址的ObjectId
。
这样:
userId
我应该使用User.findById(userId)
.deepPopulate('user_roles')
.deepPopulate('user_roles.permissions')
.distinct('permissions')
.distinct('user_roles.permissions')
.exec((err, user)=> {
if(err) res.send(err);
????
res.json(permissionsArr);
});
吗?
我可以在没有distinct
的情况下使用distinct
吗?还是必须的?
或者代替populate
我应该使用传入回调的distinct
项而不是user
使用????
参数(使用user
方法)获取所有角色,并为所有角色获取权限,然后从find
数组中删除重复项?
更新:这是使用mongoose进行休息api的结果,获取用户角色(GET http://localhost/api/users/:userId/roles):
permissionsArr
结果:
app.get('/api/users/:userId/roles', function(req,res) {
User.findById( req.params.userId )
.deepPopulate('user_roles.permissions')
.select('user_roles')
.exec((err, users)=> {
if(err) next(err);
res.json(users);
});
}
现在我需要的是{
"name": "John",
"_id": "56e677c1a7e7007d5cc245ef",
"user_roles": [
{
"_id": "56e64f057e8008263dec2cc9",
"name": "superuser",
"permissions": [
{
"name": "removeQuestion",
"_id": "56e408a9d863a8cf4d7ab001"
},
{
"name": "addQuestion",
"_id": "56e64d657e8008263dec2cc4"
},
{
"name": "addAnswer",
"_id": "56e64cf87e8008263dec2cc3"
},
{
"name": "viewQuestion",
"_id": "56e64e1e7e8008263dec2cc5"
},
{
"name": "viewAnswer",
"_id": "56e64e267e8008263dec2cc6"
}
]
},
{
"_id": "56e64ec27e8008263dec2cc8",
"name": "admin",
"permissions": [
{
"name": "addQuestion",
"_id": "56e64d657e8008263dec2cc4"
},
{
"name": "addAnswer",
"_id": "56e64cf87e8008263dec2cc3"
},
{
"name": "viewQuestion",
"_id": "56e64e1e7e8008263dec2cc5"
},
{
"name": "viewAnswer",
"_id": "56e64e267e8008263dec2cc6"
}
]
}
http://localhost/api/users/:userId/permissions以及获取用户拥有的GET
的{{1}},但删除了重复项。({ {1}}不应直接permissions
。)
感谢您的时间和任何您能提供的帮助。
答案 0 :(得分:1)
在使用您的架构测试某些代码后,我发现.distinct
只是user_roles
的值,而不是populate
的结果,例如user_roles.permissions
。这可能是填充过滤用户结果后删除重复permissions
的一种方法。
User.findById('56e7b1f74e7192381adbfdbc')
.populate({
path: 'user_roles',
model: 'Role',
populate: {
path: 'permissions',
model: 'Permission'
}
})
.exec(function(err, user) {
if (err)
console.log(err);
else {
//console.log(util.inspect(user, { showHidden: true, depth: null }));
var s = new Set();
// remove duplicate permission
user.user_roles.forEach(function(u){
u.permissions.forEach(function(p) {
s.add(p.name);
})
})
var arr = [...s]; // convert set to array
console.log(arr);
}
});
顺便说一句,您可以在不使用模块mongoose-deep-populate
的情况下以这种方式填充结果。
答案 1 :(得分:0)
实际上,您可以使用聚合框架重复删除嵌套的权限数组。您还可以选择map-reduce,但建议使用聚合框架,并且性能更高。
db.users.aggregate([
{$match:{_id:"56e677c1a7e7007d5cc245ef"}},
{$unwind:"$user_roles"},
{$unwind:"$user_roles.permissions"},
{$group:{_id:"$_id", permissions:{$addToSet:"$user_roles.permissions.name"}}}
])
根据您的示例文档,它应该提取
{
"_id" : "56e677c1a7e7007d5cc245ef",
"permissions" : [
"addAnswer",
"viewAnswer",
"viewQuestion",
"addQuestion",
"removeQuestion"
]
}
我很肯定你可以把它翻译成猫鼬,而且很容易。