0

私はmongodbとmongooseが初めてで、mongooseのドキュメントを検索すればするほど、迷子になります。フィールドの値がJohn
である があるuserとします。Johnには 2 つの があります。namerole

  • スーパーユーザー
  • 管理者

このroles のそれぞれには、次のようなものがありますpermissions

  • スーパーユーザー
    • 追加質問
    • 編集質問
    • 削除質問
  • 管理者
    • 追加質問
    • 見る答え

ご覧のとおり、それぞれに重複があります。次のように、重複のない配列でユーザーJohnroleのアクセス許可を取得するにはどうすればよいですか(この例で繰り返されるのは です)。 addQuestion

['addQuestion', 'editQuestion', 'removeQuestion', 'viewAnswer']

これは私のスキーマです:

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ご覧のとおり、配列に権限名がありません。参照がありますObjectId

userIdはURLから来ただけです。それで:

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か? 最初に ingdistinctなしで使用できますか? populateそれとも必須ですか?または、コールバックに渡されdistinctたアイテムを使用する代わりに、(メソッドを使用して)パラメーターを使用してすべてのロールを取得し、すべてのロールに対してアクセス許可を取得してから、配列から重複を削除する必要がありますか?user????userfindpermissionsArr

更新: これは、mongoose を使用して作成した残りの API の結果であり、ユーザーの役割を取得します (GET http://localhost/api/users/:userId/roles ):

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"
              }
          ]
        }

今私が必要とするのはGET http://localhost/api/users/:userId/permissionspermissionsであり、それによってユーザーが持っているのを取得しrolesますが、重複は削除されています.(直接user持つべきではありません.)permissions

お時間を割いていただき、ご協力いただきありがとうございます。

4

2 に答える 2

1

スキーマでいくつかのコードをテストした後、 のようなの結果ではなく.distinct、 の値だけが異なることがわかりました。ユーザー結果をフィルタリングして入力した後に重複を削除する1つの方法があります。user_rolespopulateuser_roles.permissionspermissions

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

于 2016-03-15T09:00:42.950 に答える