【问题标题】:many-to-many relationship - populating related data in query - Keystonejs多对多关系 - 在查询中填充相关数据 - Keystonejs
【发布时间】:2015-12-05 20:47:00
【问题描述】:

我在这里做一个 keystonejs 项目,遇到了两个模型之间关系的问题。

我有以下两种型号:

用户模型:

User.add({
    name: { type: Types.Name, required: true, index: true },
    email: { type: Types.Email, initial: true, required: true, index: true },
  number: { type: Types.Number, index: true },
    password: { type: Types.Password, initial: true, required: true }
}, 'Permissions', {
    isAdmin: { type: Boolean, label: 'Can access Keystone', index: true },
}, 'Groups', {
    groups: {type: Types.Relationship, ref: 'Group', many: true }
});

我有一个组模型

Group.add({
    name: { type: String, required: true, index: true },
    description: { type: String, initial: true, required: true, index: true}

});

我有一个聚合函数,基本上可以拉出所有有用户的组

    User.model.aggregate({$group:{'_id':'$groups'}}).exec(function(err,data){
                console.log(data);
});

我的问题是上面的聚合只通过他们的 _id 值而不是他们的名字向我显示我的组。

如何在前端填充和显示名称?很明显,后端需要 id 来引用,但前端用户无法使用。

谢谢

【问题讨论】:

  • 这是不可能的,因为您正在尝试对用户集合进行聚合。用户集合没有组集合的名称字段和MongoDb doesn't allow joins。为此,您可以在用户集合中包含名称字段,或尝试使用 DBRefs
  • 所以根据我的理解,将这些模型组合在一起会更容易。我的问题是我仍然希望能够从界面内创建组。我已经阅读了一些有关您提到的内容以及其他制作方法的内容,但到目前为止还无法理解如何完成此操作。关于如何将这两者结合起来,同时仍然保持通过管理界面添加组的能力,您还有其他建议吗?
  • 我认为在应用程序级别上会更容易。无论如何,如果您没有可能,您可以使用的另一种方法是map-and-reduce。一些例子:Multiple collections into one collection -- Merging 2 collections

标签: javascript node.js mongodb keystonejs


【解决方案1】:

你可以很容易地创造你想要的东西,所以不要气馁。您只需要了解 mongoose 中的 '.populate()' 函数。请参见下面的示例。

用户模型(稍微整理一下 - 我删除了(奇怪的?)嵌套)

User.add({
    name: { type: Types.Name, required: true, index: true },
    email: { type: Types.Email, initial: true, required: true, index: true},
    number: { type: Types.Number, index: true },
    password: { type: Types.Password, initial: true, required: true },
    isAdmin: { type: Boolean, label: 'Can access Keystone', index: true },
    groups: {type: Types.Relationship, ref: 'Group', many: true }
});

组模型 -- 请注意我在底部附近添加的 Group.relationship({}) 选项以方便管理(显示在后端引用该组的用户)

Group.add({
    name: { type: String, required: true, index: true },
    description: { type: String, initial: true, required: true, index: true}    
});

Group.relationship({ ref: 'User', path: 'users', refPath:'Groups'});

控制器获取用户列表及其所有相应的组信息

 view.on('init', function(next) {
    keystone.list('User').model.find()
    .populate('groups')
    .exec(function(err, users) {
      if(err) {
        console.log(err);
        return next(err);
      } else {
        locals.data.users = users;
        next(err);
      }
    });
  });

控制器让特定组中的用户显示在前端(您首先需要组 ID)

  view.on('init', function(next) {
    keystone.list('User').model.find()
    .where('Groups').in([array, of, group, ids])
    .populate('groups')
    .exec(function(err, users) {
      if(err) {
        console.log(err);
        return next(err);
      } else {
        locals.data.users = users;
        next(err);
      }
    });
  });

locals.data.users 在每种情况下都会像这样返回:

[
  {
    _id: '',
    name: '',
    ...
    groups: [
      {
        _id: '',
        name: ''
        ...
      }
    ]
  }
]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-07
    相关资源
    最近更新 更多