我正在尝试在我正在处理的API中放置一个嵌套的MongoDB调用。 API的目标是基于锻炼执行来更新人员目标。我目前的问题是尝试将锻炼事件纳入主要功能,以使我能够计算“完整性”。
我欢迎您就此问题发表任何意见。
大家好,
我试图在我一直在研究的API中放置一个嵌套的MongoDB调用.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: [] } ]
正如您所看到的,练习数据实际上是一个空数组,尽管在下面的原始帖子中存在数据。
解决
我忘了注意收集名称的脉动
答案 0 :(得分:1)
您应该能够使用聚合框架管道执行单个查询,即使用 $lookup
, $unwind
和 { {3}} 管道阶段,可通过 $redact
管道执行返回所需的文档。
在以下示例中, aggregate()
管道允许您对user_id
字段上的其他集合执行“左连接”,展平生成的文档数组与 $lookup
结合使用,然后使用 $unwind
过滤管道中的文档,该文件将返回与日期条件匹配的所有文档 $redact
,否则使用 $$KEEP
系统变量弃用:
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
}
}
});
};
请注意,对于每个输入文档, $$PRUNE
输出n
个文档,其中n
是数组元素的数量,对于空数可以为零数组,因此可能需要对文档进行分组
再次在 $unwind
管道之后,每个目标可能会有(n-x)
个文档,其中n
是exercises数组的长度> $redact
和x
是 $lookup
之后滤出的元素数。
作为上述内容的后续行动,要对文档进行分组并获得预期的输出,您需要一个最终的 $redact
管道,按_id
键对文档进行分组,使用 $group
累加器运算符返回goal_id
字段,并使用 $first
累加器创建exercises
数组。以下管道演示了这一点:
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
}
}
});
};