MongoDBcallback问题的嵌套调用

我正试图在我一直在工作的API中放置一个嵌套的MongoDB调用。 API的目标是根据练习执行更新人员目标。 我现在所面临的问题是试图将锻炼事件变成主要function,以使我能够计算“完整性”。

我欢迎您就此问题提出的任何意见。

大家好,

我试图把一个嵌套的MongoDB调用放在我一直在做的API中。API的目标是根据运行执行更新一个人的目标。我现在的问题是试图把运动事件放到主函数中使我能够计算“完整性”。

我欢迎您就此问题提出的任何意见。

module.exports.generateGoal = function(request, response) { //User ID var user_id = new ObjectId(request.params.id); //Goal Search Goals.find({ user_id: user_id, active_goal: true }, function(err, goals) { if (err) { //Error: send error to user throw err } else { if (goals.length == 0) { //No goals, do nothing return response.json({ success: true, msg: "No Goal" }); } else { //User as goals, therefore pull in exercise for (i = 0; i < goals.length; i++) { //Looking to have exercise available here for computation queryExercise(user_id, goals[i].start_date, goals[i].end_date, function(result) { //Exercise able to be accessed here console.log(result) return result }); } } } }); }; function queryExercise(user_id, start_date, end_date, callback) { ExerciseData.find({ user_id: user_id, exercise_date: { $gte: start_date, $lt: end_date } }, function(err, result) { if (err) { console.log(err); } else if (result.length > 0) { callback(result); } }); } 

编辑2:

我非常感谢下面的回应,正是我所需要的。 思考未来,任何目标可以有多个练习什么是最好的方法来获得输出类似于:

  { _id: dfhdjds8348hhj8 goal_id: 1 exercises: { { exercise: 1, type: running }, { exercise: 2, type: running } } }. { _id: ddhdjds8342hhj8 goal_id: 2 exercises: { { exercise: 1, type: jumping }, { exercise: 2, type: rowing } } } 

编辑3:

在执行下面的新代码之后,我注意到它不能够返回正确的值。 我想提供一些关于我使用的模态和语法的更多信息。

目标

 var mongoose = require('mongoose'); // Define goal model schema var GoalsSchema = new mongoose.Schema({ user_id: { type: mongoose.Schema.Types.ObjectId, required: true }, active_goal: Boolean, goal_id: Number, start_date: Date, end_date: Date }, { timestamps: true }); // Export user model module.exports = mongoose.model('Goals', GoalsSchema); 

锻炼数据

 var mongoose = require('mongoose'); // Define user model schema var exercisesSchema = new mongoose.Schema({ user_id: { type: mongoose.Schema.Types.ObjectId, required: true }, exercise_date: Date, exercise_type: String }, { timestamps: true }); // Export user model module.exports = mongoose.model('exercises', exercisesSchema); 

而我在代码中使用的语法如下所示,而不是为了使其正常工作而必须做出的其他更改。

 module.exports.generateGoal = function(request, response) { //User ID var user_id = new ObjectId(request.params.id); //User ID //Goal query Goals.aggregate([{ "$match": { "user_id": user_id, "active_goal": true } }, { "$lookup": { "from": "exercises", "localField": "user_id", "foreignField": "user_id", "as": "exercises" } }, { "$unwind": { "path": "$exercises", "preserveNullAndEmptyArrays": true } }, { "$redact": { "$cond": [{ "$and": [{ "$gte": ["$exercises.exercise_date", "$exercises.start_date"] }, { "$lte": ["$exercises.exercise_date", "$exercises.end_date"] } ] }, "$$KEEP", "$$PRUNE" ] } }, { "$group": { "_id": "$_id", "goal_id": { "$first": "$goal_id" }, "exercises": { "$push": "$exercises" } } } ], function(err, goalOut) { console.log(goalOut) if (err) { //Error: send error to user throw err } else { if (goalOut.length == 0) { //No goals, do nothing return response.json({ success: true, msg: "No Goal", statusCode: 0, payload: 'na' }); } else { //User as goals + matching exercise //console.log(goals); return response.json({ success: true, msg: "Goals", payload: goalOut }); } } }); }; 

其中输出以下内容:

 [ { _id: 58c3e0b1c8a467055d900595, goal_id: 1, exercises: [] }, { _id: 58c3e0adc8a467055d900594, goal_id: 2, exercises: [] } ] 

正如你可以看到练习数据实际上是一个空的数组,尽pipe在原始文章下面的数据是存在的。

解决了

我忘了注意收集名称的脉动

您应该能够使用聚合框架pipe道执行单个查询,即使用$lookup$unwind$redactpipe道阶段通过aggregate()pipe道执行返回所需的文档。

在以下示例中, $lookuppipe道允许您对user_id字段上的其他集合执行“左连接”,将由于使用$unwind进行连接而生成的文档数组平铺,然后过滤stream水线中的文档用$redact返回与使用$$KEEP匹配date条件的所有文档,否则使用$$PRUNE系统variables抛弃:

 module.exports.generateGoal = function(request, response) { //User ID var user_id = new ObjectId(request.params.id); //Goal query Goals.aggregate([ { "$match": { "user_id": user_id, "active_goal": true } }, { "$lookup": { "from": "exercises", "localField": "user_id", "foreignField": "user_id", "as": "exercises" } }, { "$unwind": "$exercises" }, { "$redact": { "$cond": [ { "$and": [ { "$gte": ["$exercises.exercise_date", "$start_date"] }, { "$lt": ["$exercises.exercise_date", "$end_date"] } ] }, "$$KEEP", "$$PRUNE" ] } } ], function(err, goals) { if (err) { //Error: send error to user throw err } else { if (goals.length == 0) { //No goals, do nothing return response.json({ success: true, msg: "No Goal" }); } else { //User as goals + matching exercise console.log(goals); return goals } } }); }; 

请记住,对于每个input文档, $unwind输出n文档,其中n是数组元素的数量,对于空数组可能为零,因此可能需要在$redactpipe道之后再次对文档进行分组每个目标可能有(nx)文档,其中n$lookup之后生成的exercises数组的长度, x$redact之后过滤出的元素的数量。


UPDATE

作为上述的后续工作,为了对文档进行分组并获得预期的输出,您需要一个最终的$grouppipe道,通过_id键对文档进行分组,使用$first accumulator运算符返回goal_id字段并使用$push累加器。 以下pipe道演示了这一点:

 module.exports.generateGoal = function(request, response) { //User ID var user_id = new ObjectId(request.params.id); //Goal query Goals.aggregate([ { "$match": { "user_id": user_id, "active_goal": true } }, { "$lookup": { "from": "exercises", "localField": "user_id", "foreignField": "user_id", "as": "exercises" } }, { "$unwind": "$exercises" }, { "$redact": { "$cond": [ { "$and": [ { "$gte": ["$exercises.exercise_date", "$start_date"] }, { "$lt": ["$exercises.exercise_date", "$end_date"] } ] }, "$$KEEP", "$$PRUNE" ] } }, { "$group": { "_id": "$_id", "goal_id": { "$first": "$goal_id" }, "exercises": { "$push": "$exercises" } } } ], function(err, goals) { if (err) { //Error: send error to user throw err } else { if (goals.length == 0) { //No goals, do nothing return response.json({ success: true, msg: "No Goal" }); } else { //User as goals + matching exercise console.log(goals); return goals } } }); };