Mongo:存储文档的用户特定数据

时间:2014-09-16 13:20:49

标签: node.js mongodb mongoose

我想存储文档的用户特定数据。

集合Task包含一般信息,但也应包含特定于用户的信息。查询API客户端时,应仅获取请求用户的一般信息和特定信息。

我想到了不同的方法,最后得到了以下两个方法。请分享您对此类问题的意见和建议,因为我认为这是一个常见问题。

谢谢。

A - 嵌入式阵列

  • Tasks包含一系列子文档,其中包含每个用户的设置
  • 在返回任务之前,数组将被特定于用户的对象替换,或者该对象将与任务本身合并(我更喜欢第一个,因此每个人都可以看到哪些字段是特定于用户的)

示例

// Task
{
  "title": "brush your teeth",
   ...
  "user_based": [
    {
      "user": "54182b021a944f9c18897642",
      "context": "Work",
      "remind": "2014-09-16T12:41:16.412Z",
      "last_access": "2014-09-16T12:41:16.412Z"
       ...
    }
  ]
}

问题

  • 需要进行计算(比较)和操作
  • Mongoose支持在发送对象之前对其进行操作的方法,但由于此时用户未知,因此无法在此处使用

B - UserTask-Collection

  • Tasks包含一般信息
  • UserTasks包含特定于用户的信息,并引用Task
  • 查询
  • UserTasks并将Task解析为子文档

示例

// Task
{
  "title": "brush your teeth",
  ...
}

// UserTask
{
  "task": "54282b021a944f9c18897642",
  "context": "Work",
  "remind": "2014-09-16T12:41:16.412Z",
  "last_access": "2014-09-16T12:41:16.412Z"
   ...
}

问题

  • 需要解析参考
  • 如果UserTasks没有Task
  • ,则可能存在不一致
  • 如果没有创建导致其他问题的Task,则UserTask不能存在

2 个答案:

答案 0 :(得分:3)

在我看来,方法B更适合你想要完成的任务。

由于任务请求应仅返回一般信息和请求用户的特定数据,因此在单独的集合中请求它比在嵌套数组中包含它更容易。使用一些preSave和preRemove挂钩可以始终解决数据不一致的问题,以确保任务至少有一个用户任务,并且用户任务始终连接到任务。

方法A的问题需要更多代码来从嵌套数组中提取用户特定数据并将其返回给用户,使用方法B,这将非常简单,实际上相当优雅,让我举个例子:

var getTask = function(req, res, next) {
    Task.findById(req.params.id, function(err, task) {
        if (err) ...
        UserTask.findOne({
            user: req.user._id,
            task: task._id
        }, function(err, userTask) {
            task.userTask = userTask;
            res.json(task);
        })
    })
};

如果这是有道理的,请告诉我。

答案 1 :(得分:3)

总的来说,我总是希望尽可能简单快速地检索数据。

我倾向于选择较少的集合(解决方案A),因为它将减少解析引用的需要。但是,在将数据发送到客户端之前,我不想操纵数据。这为错误和安全漏洞打开了大门。

在这种情况下,我会选择解决方案B.您可以使用mongoose populate功能来减少解决mongo中引用的难度。

// loading all tasks for a user
router.get('/users/:id/tasks', function(req, res, next) {
  UserTask.find({_user: req.params.id})
    .populate('_tasks')
    .exec(function(err, tasks) {
      if(err) return next(err);
      res.json(tasks)
  })
})