我有两个函数,一个是“ calcID”,用于在使用MongoDB聚合框架和mongoose进行一些计算之后计算所传递的demo_id是否与文档_id相匹配;另一个函数是“ getDemoID”,该函数使用该先前的函数来获取带有计算出的ID,然后进一步处理文档(例如记录某些ID)...:
var calcID = function(demo_id) {
//e.g. demo_id = 928106329281
var result = FlexPotenzial.aggregate([
{
$addFields: {
subID: {
"$eq": [{"$trunc": {"$divide": ["$_id", 1000000]}},+demo_id]
}
}
},
{
"$match": { subID : true }
}
])
}
exports.getDemoID = function(req,res) {
calcID(req.params.demo_id, function(err, flPot) {
flPot => {
for (let doc of flPot) {
console.log(doc.id);
}
}
}
).catch(e => { console.log(e); res.error(e);});
}
问题是,我的calcID函数显然未返回任何内容,尽管我在猫鼬外壳中测试了聚合,并且语法正确,但是当在路由url中将id作为url参数传递时,我没有得到任何返回值(获取方法)... 我想对功能进行更多的模块化,以便可以重用经常重复的代码...
我现在的问题是,如何在聚合阶段将找到的文档传递给第二个函数并在那里使用它们?对于Node或一般的javascript样式,我还很陌生,我不确定返回的聚合框架结果的类型是什么……也许根本不可能吗?
答案 0 :(得分:0)
您需要传递回调以进行汇总,或者在完成操作后使用.exec()
从中获得承诺。即使不是真正的承诺,猫鼬中的许多东西也可以使用.then(),而Aggregate就是其中之一。但是,如果您进行了aggregate(...)。exec(),您将始终得到真正的保证。
由于我们在这里谈论快递,所以一直都是中间件。只需将您的东西贴在req
上,然后继续前进即可。
async function myMiddleware(req, res, next) {
const { demo_id } = req.params;
req.results = await FlexPotenzial.aggregate([
{
$addFields: {
subID: {
"$eq": [{"$trunc": {"$divide": ["$_id", 1000000]}},+demo_id]
}
}
},
{
"$match": { subID : true }
}
]).exec();
next();
}
// All routes matching this will use the middleware
app.use('/aggregate-me/:demo_id*', myMiddleware);
// And then we can access req.results anywhere further down the stream....
app.get('/aggregate-me/:demo_id/something', doSomething);
app.get('/aggregate-me/:demo_id/somethingElse', doSomethingElse);
您还可以将中间件用于单个路由
app.get('/something-entirely-different/:demo_id', myMiddleware, (req,res)=>{
res.json(results);
});
甚至:
app.get('/abc', [tonsof, middleware, inAnArray], endpoint);
规则是继续使用next()
来继续中间件链,并使用某种res.end
来结束中间件链。