Javascript 在mongoDB/Mongoose上使用find和aggregate获取数据
我正在做一个node.js项目,在前端使用图表显示一些数据 我对我的路线有以下两个问题:Javascript 在mongoDB/Mongoose上使用find和aggregate获取数据,javascript,node.js,mongodb,express,mongoose,Javascript,Node.js,Mongodb,Express,Mongoose,我正在做一个node.js项目,在前端使用图表显示一些数据 我对我的路线有以下两个问题: atendimentos.find({}) .then(atendimentos => { final = atendimentos.filter(atendimentos => atendimentos.status === 'F') testeea = atendimentos.filter(atendimentos =
atendimentos.find({})
.then(atendimentos => {
final = atendimentos.filter(atendimentos => atendimentos.status === 'F')
testeea = atendimentos.filter(atendimentos => atendimentos.status === 'EA')
res.render('home', {user: req.user, fin: final.length, ea: testeea.length});
//Funciona
console.log(final.length)
})
.catch(err => console.error(err));
atendimentos.aggregate([
{ $project:
{ _id: "$month",
year: {$year: "$date" },
month: { $month: "$date"},
amount: 1
}
},
{ $group:
{ _id: { year: "$year", month: ("$month")},
sum: { $sum: 1}
}
}]).exec(function(error, items){
if(error){return next(error);}
console.log(items);
});
编辑1:
所以,输入数据。。。我想我没有,因为我实际上是通过查询从数据库中获取所有信息的。我期望的数据是在图表上呈现的状态为F或EA的文档/对象
数据库大约有8.5k个文档,F one返回8041个文档,EA返回351个文档,这是一个简单的数组,其中的数字在我的路径上使用.length返回。这些数字显示在图表上
现在,关于聚合部分,我尝试使用集合创建一个表。我打算显示每月的支持电话(ATendmentos)数量。它实际上记录了正确的数据,如下所示:
[ { _id: { year: 2018, month: 6 }, sum: 4005 },
{ _id: { year: 2018, month: 7 }, sum: 43 },
{ _id: { year: 2018, month: 5 }, sum: 3996 },
{ _id: { year: 2018, month: 4 }, sum: 434 } ]
我想使用这些数据在我的视图中呈现表
编辑1结束
编辑2
router.get('/home', isAuthenticated, async (req, res, next) => {
let final;
let testeea;
atendimentos.find({})
.then(atendimentos => {
final = atendimentos.filter(atendimentos => atendimentos.status === 'F')
testeea = atendimentos.filter(atendimentos => atendimentos.status === 'EA')
res.render('home', {user: req.user, fin: final.length, ea: testeea.length});
//Funciona
console.log(final.length)
})
.catch(err => console.error(err));
所以,这里是路线,另一部分只是我尝试过的聚合查询和结束括号。如您所见,我获取数据并使用Array.filter过滤获取的结果,使用status=F或=EA
它返回数组的长度,因此它计算每个字母的状态数。这个数字在图表中呈现,因为我将它作为fin:final.length和ea:testeea.length发送到前端。这里没有格式化数据或类似的东西。这样没关系
与每月返回呼叫的聚合部分相关,我只想使用每月和每年的呼叫数。在这一部分中,我期望得到如下数据:[{u id:{year:2018,month:6},sum:4005}
我希望能够像获取fin和ea一样获取数据,使用.length进行计数并将其放入视图中
编辑2结束
router.get('/home', isAuthenticated, async (req, res, next) => {
let final;
let testeea;
atendimentos.find({})
.then(atendimentos => {
final = atendimentos.filter(atendimentos => atendimentos.status === 'F')
testeea = atendimentos.filter(atendimentos => atendimentos.status === 'EA')
res.render('home', {user: req.user, fin: final.length, ea: testeea.length});
//Funciona
console.log(final.length)
})
.catch(err => console.error(err));
两者都返回了我所需要的内容,问题是我不能将聚合查询放在find查询之前,并将items:items添加到render方法。我想知道如何执行这些查询以显示与我在这两个查询上获取的内容相同的内容。提前感谢!MongoDB Server 3.2及以下版本
您需要运行两个聚合查询并合并结果中的对象。这可以通过多种方式完成,但可以向您展示Promise方式和async/await方式
1.使用承诺
router.get('/home', isAuthenticated, (req, res, next) => {
const counts = atendimentos.aggregate([
{ '$group': {
'_id': null,
'fin': {
'$sum': {
'$cond': [ { '$eq': [ '$status', 'F' ] }, 1, 0 ]
}
},
'ea': {
'$sum': {
'$cond': [ { '$eq': [ '$status', 'EA' ] }, 1, 0 ]
}
}
} }
]).exec();
const monthly = atendimentos.aggregate([
{ '$group': {
'_id': {
'year': { '$year': '$date' },
'month': { '$month': '$date' }
},
'sum': { '$sum': 1 }
} },
{ '$group': {
'_id': null,
'back': { '$push': '$$ROOT' }
} },
]).exec();
Promise.all([ counts, monthly ]).then(([ counts, monthly ]) => {
const statusData = counts[0];
const monthlyData = monthly[0];
const data = {...statusData, ...monthlyData, user: req.user};
console.log(JSON.stringify(data, null, 4));
res.render('home', data);
}).catch(err => next(err));
});
2.使用异步/等待
router.get('/home', isAuthenticated, async (req, res, next) => {
try {
const counts = await atendimentos.aggregate([
{ '$group': {
'_id': null,
'fin': {
'$sum': {
'$cond': [ { '$eq': [ '$status', 'F' ] }, 1, 0 ]
}
},
'ea': {
'$sum': {
'$cond': [ { '$eq': [ '$status', 'EA' ] }, 1, 0 ]
}
}
} }
]).exec();
const monthly = await atendimentos.aggregate([
{ '$group': {
'_id': {
'year': { '$year': '$date' },
'month': { '$month': '$date' }
},
'sum': { '$sum': 1 }
} },
{ '$group': {
'_id': null,
'back': { '$push': '$$ROOT' }
} },
]).exec();
const statusData = counts[0];
const monthlyData = monthly[0];
const data = {...statusData, ...monthlyData, user: req.user};
console.log(JSON.stringify(data, null, 4));
res.render('home', data);
} catch (err) {
next(err);
}
});
MongoDB服务器3.4.4及以上版本 聚合管道还可以处理过滤,您只需要使用管道步骤,该步骤能够在同一组输入文档的单个阶段内处理多个聚合管道。每个子管道在输出文档中都有自己的字段,其结果存储为文档数组。 考虑运行以下管道:
atendimentos.aggregate([
{ '$facet': {
'counts': [
{ '$group': {
'_id': null,
'fin': {
'$sum': {
'$cond': [ { '$eq': [ '$status', 'F' ] }, 1, 0 ]
}
},
'ea': {
'$sum': {
'$cond': [ { '$eq': [ '$status', 'EA' ] }, 1, 0 ]
}
}
} }
],
'monthly': [
{ '$group': {
'_id': {
'year': { '$year': '$date' },
'month': { '$month': '$date' }
},
'sum': { '$sum': 1 }
} },
{ '$group': {
'_id': null,
'items': { '$push': '$$ROOT' }
} },
]
} },
{ '$replaceRoot': {
'newRoot': {
'$mergeObjects': {
'$concatArrays': ['$counts', '$monthly']
}
}
} }
]).exec((err, results) => {
const data = results[0];
console.log(data);
res.render('home', { user: req.user, ...data });
})
所以所有的数据都将返回到这个结果数组中,对吗?我有点困惑,因为在我的图表配置中,我有一个将数据呈现到图表中的方法。我不知道如何使用结果数组访问这些数据,我不清楚。按照您的要求进行编辑,希望有用!谢谢您编辑我的问题,我希望如此您需要澄清一个您正在传递给视图的所需数据的示例,即
res.render('home',data)
。您只解释了返回汇总月度计数的部分,但没有指定最终/总体预期结果,例如,您是否预期{user:“test\u user”之类的数据,fin:8500,ea:8041,项目:[{id:{年份:2018,月份:6},总和:4005},{id:{年份:2018,月份:7},总和:43},}
?已编辑,现在我已经放置了路径并解释了更多内容。感谢后续的编辑,但我觉得我的观点在某个地方迷失了方向;我只是想了解客户端从服务器期望的数据,使用您想要的示例JSON数据进行编辑就足够了,但您只显示了不连贯的数据。您是否尝试在中运行管道上面的答案,如果是,结果数组是否符合您的期望?如果不是,请告诉我需要传递给视图的整体预期JSON输出的示例。