【发布时间】:2018-02-27 00:06:39
【问题描述】:
对 mongo 很陌生,我不知道哪种方法最适合对我的引用数据进行连接。我不确定我是否应该做两次拉动。
我有一个运行猫鼬的节点应用程序。它是议程项目的集合,每个项目都有任务。
以下是相关架构的信息:
议程架构:
var agendaSchema = new mongoose.Schema({
type : {type: String, required: true},
description : {type: String, required: true},
status: { type: String, enum: ['New', 'Assigned', 'Closed'], required: true },
followup: {type: Date},
created: {type: Date, default: Date.now()},
assigned : String,
crq_nbr : Number,
tasks : [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Task"
}
]
});
任务架构:
var taskSchema = mongoose.Schema({
created : { type: Date, default: Date.now },
completed : { type: Date, default: Date.now },
status: {type: String, enum: ["Open","Closed"]},
author: {
id : { type: mongoose.Schema.Types.ObjectId, ref: "User" },
name: String
},
text : String,
updated : Date
});
我正在尝试提取所有具有“已完成”状态的任务的议程项目。
我的一个想法是提取所有议程项目,根据 $match 填充它们。之后,我会使用 javascript 过滤掉所有没有任务的议程项目。
例如:(还是要加上 $date 条件)
Agenda.find({}).populate({
"path": "tasks",
"match": {"status" : "Closed"}
}).exec(function(err, foundAgenda) {
let newAgenda = foundAgenda.filter(function(agenda) {
if (agenda.tasks.length > 0) return true;
})
res.send(newAgenda);
});
我的另一个可怕的想法是找到所有任务并找到 ID,然后根据这些 ID 找到议程并填充它。这样做的问题不仅在于它是两个单独的查询
Task.find({ "status": "Closed"}, { _id: 1 }, function(err, foundTasks) {
if (err) {} else {
var taskArray = [];
foundTasks.forEach(function(task) {taskArray.push(task)});
Agenda.find({"tasks" : {$in : foundTasks}}, function(err, foundAgenda) {
res.send(foundAgenda);
});
}
});
这两种方法都可能对我有用,但我相信还有更好的方法。这种连接的最佳方法是什么?
【问题讨论】:
-
通常您会使用
$lookup为每个议程拉取任务,然后过滤具有已完成状态的任务。
标签: node.js mongodb mongoose mongodb-query aggregation-framework