【问题标题】:Mongoose model with array logic具有数组逻辑的猫鼬模型
【发布时间】:2016-06-28 12:49:51
【问题描述】:

我目前正在使用 Mongoose 进行培训,为此我正在构建一个小型消息传递应用程序。

我有一个用户集合,这里是 User.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var UserSchema = new Schema({
  username: String,
  password: String
});

module.exports = mongoose.model('User', UserSchema);

现在我想编写一个包含用户列表的聊天室模型,我应该如何进行?这是我目前的 Chatroom.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var ChatroomSchema = new Schema({
  name: String,
  password: String,
  members: ???
});

module.exports = mongoose.model('Chatroom', ChatroomSchema);

最后我想知道在创建聊天室时如何在该成员数组中发布用户,这是我的 /chatroom 路由代码:

router.route('/chatroom')
.post(function(req, res) {
  var chatroom = new Chatroom();
  chatroom.name = req.body.name;
  chatroom.password = encrypt(req.body.password,chatroom.name);
  chatroom.members = ???;

  chatroom.save(function(err) {
    if (err)
      res.send(err);

    res.json({ message: 'Chatroom created!' });
  });
});

有没有一种特定的方法可以将用户绑定到成员数组,或者我应该将成员定义为字符串数组:

members : {username:String}

【问题讨论】:

    标签: arrays node.js mongodb express mongoose


    【解决方案1】:

    在您的情况下,人口将是理想的。来自docs

    填充是自动替换指定的过程 文档中的路径以及来自其他集合的文档。

    Population 将无缝帮助您将 Users 集合中的数据引入您的 Chatroom 模型。考虑以下示例来说明这种方法:

    var mongoose = require('mongoose');
    var Schema = mongoose.Schema;
    
    var ChatroomSchema = new Schema({
        name: String,
        password: String,
        members: [{ type: Schema.Types.ObjectId, ref: 'User' }]
    });
    
    module.exports = mongoose.model('Chatroom', ChatroomSchema);
    

    在您的聊天室架构定义中,您通过将字段定义 members 括在方括号中来为每个对象添加一个主代理键列表,称为 ObjectId,在数据中引用为 _id 以获得此功能。这些将是用于引用 User 集合中的文档的键。

    注意:- 定义引用时,ref 属性必须与模型定义中的模型名称完全匹配,否则会出错(假设您引用不存在的 @ 987654331@型号或Users)

    MissingSchemaError: Schema hasn't been registered for model "Member"..
    

    读取数据

    这就是 Mongoose 种群通过其 populate() 函数显示文档读取非常简单和快速的地方。因此,例如,要在聊天室中显示引用的 users,请调用 populate() 方法,并将字符串中该字段的名称作为参数,例如

    Chatroom.findOne({"_id": chatId})
        .populate("members")
        .exec(err, chats) { ... }
    

    写入数据

    当您为Chatroom 模型保存数据时,您还需要保存对用户的引用。例如,当创建一个新的 Chatroom 时,您需要将一个 User 引用数组保存为成员字段:

    router.route('/chatroom')
    .post(function(req, res) {
        var chatroom = new Chatroom();
        var usersIds = ["54b5659536cd5250a3a93bd3", "54b5659836cd5250a3a93bd4"]; // <-- an array with members ids, for example.
        chatroom.name = req.body.name;
        chatroom.password = encrypt(req.body.password,chatroom.name);
        chatroom.members = usersIds; 
    
        chatroom.save(function(err) {
            if (err)
                res.send(err);
            res.json({ message: 'Chatroom created!' });
        });
    });
    

    【讨论】:

    • 感谢您的回答,非常有帮助!我正在使用令牌身份验证,我目前正在令牌内存储用户名。我正在考虑存储 User ObjectID 以避免在成员数组中定义第一个用户时必须执行另一个请求以获取带有用户名的 ID。你知道这方面有什么好的做法吗?
    • 您几乎可以在成员字段中使用任何数据类型,只要它是引用模型的唯一标识符,因此在这种情况下,它不仅限于 ObjectId,您还可以使用用户名作为参考,例如members: [{ type: String, ref: 'User' }] 然后在保存聊天室实例时保存用户名数组。因此,当您可以只使用用户名(这也是唯一的)时,这也为您省去了将用户的 ObjectId 存储在令牌中的麻烦。这是另一种选择,但通常取决于您的应用程序需求。
    • 在这种情况下填充仍然有效吗?如果我使用用户名而不是 ObjectID ?我现在有这个错误(我的请求的 JSON 结果):{ "message": "Cast to ObjectId failed for value \"test\" at path \"_id\"", "name": "CastError", "kind": "ObjectId", "value": "test", "path": "_id" } 这是我的请求:.get(function(req, res) { Chatroom.find({ 'members': req.decoded.username }).populate("members").exec(function(err, chatrooms) { ... });});
    • 忘了提及,如果您想使用 username 作为您的用户参考,那么您必须在您的 User 架构定义中将 _id 定义为 String,因为默认情况下Mongoose 将 _id 字段视为 ObjectId
    • 好吧,实际上我不能使用我需要使用 _id 的用户名,对吗?所以我必须在这个 _id 字段中存储用户名,而不是我创建的自定义用户名字段?
    【解决方案2】:

    尝试参考文档

    Chatroom.js

    var ChatroomSchema = new Schema({
      name: String,
      password: String,
      members: [Schema.Types.ObjectID, ref = 'user']
    });
    

    控制器

    router.route('/chatroom')
    .post(function(req, res) {
      var chatroom = new Chatroom();
      chatroom.name = req.body.name;
      chatroom.password = encrypt(req.body.password,chatroom.name);
      chatroom.members = req.user; // if the user is authenticated
    
      chatroom.save(function(err) {
        if (err)
          res.send(err);
    
        res.json({ message: 'Chatroom created!' });
      });
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-13
      • 2014-11-14
      • 1970-01-01
      • 2017-06-30
      • 2016-06-29
      • 1970-01-01
      • 1970-01-01
      • 2017-10-05
      相关资源
      最近更新 更多