在mongodb的聚合里面调用函数?

采集:

[ { _id: "Foo", flag1: false, flag2: true, flag3: false }, { _id: "Bar", flag1: true, flag2: false, flag3: true } ] 

我的问题是,是否有可能调用聚合查询内的方法?

 aggregate({ $project: { '_id': 1, 'status' MyService.getStatus($flag1, $flag2, $flag3) } }); 

如果可能的话,它的语法是什么? 结果:

 [ { _id: "Foo", status: 'ok' }, { _id: "Bar", status: 'broken' } ] 

在我的真实世界的应用程序,我有10个布尔标志每个文件。 如果用户得到这个文件,我想转换标志并赋予它们一个含义(对于用户)。 例如考虑一个文件代表一个轮胎。

 flag1 = true means tire have good pressure, false means low pressure flag2 = true means depth of tire profile is good, false means little profile and so on 

所以总的来说,我想说轮胎是可以的

  flag1, flag2 are true and flag3 is false 

轮胎需要更换(损坏或更换)

 flag1, flag2 are false and flag3 is true 

当一个文档返回给用户的标志应该被删除。 相反,我们有状态字段,说轮胎是好的或损坏。

外部函数不适用于聚合框架。 所有东西在input时都被parsing为BSON,所以不允许任何JavaScript或其他东西。 这基本上都是从BSON“操作符”定义处理到本地C ++代码实现,所以它真的很快。

这就是将您的预期逻辑“转化”为汇总框架可以处理的内容。 实际上有“逻辑”运算符,如$or $and ,在这种情况下工作:

 db.collection.aggregate([ { "$project": { "_id": 1, "status": { "$cond": [ { "$or": [ // Your first set of rules requires "false" for "flag1" or // "flag2" and "true" for "flag3" { "$and": [ { "$not": [ { "$or": [ "$flag1", "$flag2" ] }, ]}, "$flag3" ]}, // Your second set of rules requires "true" for "flag1" or // "flag2" and "false" for "flag3" { "$and": [ { "$or": [ "$flag1", "$flag2" ] }, { "$not": [ "$flag3" ] } ]}, ]}, "ok", "broken" ] } }} ]) 

所以没有外部function,只需要和汇聚框架提供的运算符一起实现逻辑即可。 除了基本的逻辑实现之外,为了提供与true/false评估不同的结果, $not “倒转”作为“三元”的ligic和$cond

聚合调用可以传递一个callback函数,在聚合完成后调用。

 function getValuesAndMessges( params, callback ) { db.collection.aggregate([ { "$project": { "_id": 1, "flag1": { "$first": "$flag1" }, "flag2": { "$first": "$flag2" }, "flag3": { "$first": "$flag3" }, }} ], function( err, results ) { if ( !err ) { result.forEach( result => { // process items in results here, setting a value // using the actual logic for writing message ... if( flag1 ) result.message = "broken"; else result.messsge = 'OK'; }); } callback(err, results); }); } 

这样你的每个聚合项目(根据你的条件/参数)将有一个消息属性(或你select写的任何属性)设置,你可以在你的调用函数中使用它们。