我想存储文档的用户特定数据。
集合Task
包含一般信息,但也应包含特定于用户的信息。查询API客户端时,应仅获取请求用户的一般信息和特定信息。
我想到了不同的方法,最后得到了以下两个方法。请分享您对此类问题的意见和建议,因为我认为这是一个常见问题。
谢谢。
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"
...
}
]
}
问题
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
不能存在答案 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)
})
})