查询和连接引用的数据

时间:2017-09-28 20:39:41

标签: node.js mongodb mongoose mongodb-query aggregation-framework

对mongo来说很新,我无法弄清楚哪种方法最适合加入我引用的数据。我不确定我是否应该做两次拉动。

我有一个运行mongoose的节点应用程序。它是一系列议程项目,每个项目都有任务。

以下是相关模式的信息:

议程架构:

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过滤掉任何没有任务的议程项目。

Ex :(仍然需要添加$ 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);
        });
    }
});

这些都可能对我有用,但我确信有更好的方法。这种类型的加入的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

也许可以尝试这个模块https://www.npmjs.com/package/@coolgk/mongo

下面的查询只会为您提供具有"已关闭"的任务的议程行。状态。

Agenda.find({}, {
    join: {
        on: 'tasks',
        filters: {
            'status' : 'Closed'
        }
    }
})

更多例子:

加入

SQL to @coolgk/mongo
左加入
SELECT * FROM a LEFT JOIN b ON a.b_id = b.id

变为

model.find({}, {
    join: [ { on: 'b_id' } ]
})

结果:

[{
    _id: '5a8bde4ae2ead929f89f3c42',
    a_name: 'aname1',
    b_id: {
        _id: '5a8bde4ae2ead929f89f3c41',
        b_name: 'bname1'
    }
}, { ... }, ... ]
内约加入约束
SELECT * FROM a, b WHERE a.b_id = b.id AND b.b_name = 'bname1'

变为

model.find({}, {
    join: [ { on: 'b_id', filters: { b_name: 'bname1' } } ]
})

结果:

[{
    _id: '5a8bdfb05d44ea2a08fa8a4c',
    a_name: 'aname2',
    b_id: {
        _id: '5a8bdfb05d44ea2a08fa8a4b',
        b_name: 'bname2'
    }
}]
内部加入Mulitple馆藏
SELECT * FROM a, b, c WHERE a.b_id = b.id AND b.c_id = c.id AND c.c_name = 'cname3'

modela.find({}, {
    join: [{
        on: 'b_id',
        join: [{
            on: 'c_id',
            filters: { c_name: 'cname3' }
        }]
    }]
})

结果:

[{
    _id: '5a8bdfc1b07af22a12cb1f0b',
    a_name: 'aname3',
    b_id: {
        _id: '5a8bdfc1b07af22a12cb1f0a',
        b_name: 'bname3',
        c_id: {
            _id: '5a8bdfc1b07af22a12cb1f09',
            c_name: 'cname3'
        }
    }
}]

PS。我创建了这个模块。