mongodb使用聚合管道、MapReduce或runCommand中存储的JavaScript函数 2 周 Questions & Answers 5370 有没有办法在pipeline或mapreduce中使用另存为db.system.js.save(...)的用户定义函数
# 1 楼答案 保存到system.js的任何函数都可供^{}运算符和^{}等“JavaScript”处理语句使用,并可由_id值引用 db.system.js.save({ "_id": "squareThis", "value": function(a) { return a*a } }) 以及“样本”收集中插入的一些数据: { "_id" : ObjectId("55aafd2bacbed38e06f9eccf"), "a" : 1 } { "_id" : ObjectId("55aafea6acbed38e06f9ecd0"), "a" : 2 } { "_id" : ObjectId("55aafeabacbed38e06f9ecd1"), "a" : 3 } 然后: db.sample.mapReduce( function() { emit(null, squareThis(this.a)); }, function(key,values) { return Array.sum(values); }, { "out": { "inline": 1 } } ); 给出: "results" : [ { "_id" : null, "value" : 14 } ], 或与$where一起: db.sample.find(function() { return squareThis(this.a) == 9 }) { "_id" : ObjectId("55aafeabacbed38e06f9ecd1"), "a" : 3 } 但在“两者都不”的情况下,您不能使用全局变量,例如数据库db引用或其他函数。$where和mapReduce文档都包含关于您在这里可以做什么的限制的信息。所以,如果你认为你要做“在另一个集合中查找数据”之类的事情,那么你可以忘记它,因为它是“不允许的” 每个MongoDB命令操作实际上都是对“引擎盖下”的“runCommand”操作的调用。但是,除非该命令实际上是在“调用JavaScript处理引擎”,否则它的用法就变得无关紧要了。无论如何,只有少数几个命令可以做到这一点,它们是mapReduce、group或eval,当然还有$where的find操作 聚合框架不以任何方式使用JavaScript。正如其他人所做的那样,你可能误解了这样一句话,它并没有达到你认为的效果: db.sample.aggregate([ { "$match": { "a": { "$in": db.sample.distinct("a") } }} ]) 也就是说,“没有在聚合管道内运行”,而是在将管道发送到服务器之前,对.distinct()调用的“结果”进行“评估”。就像使用外部变量一样: var items = [1,2,3]; db.sample.aggregate([ { "$match": { "a": { "$in": items } }} ]) 两者基本上都以相同的方式发送到服务器: db.sample.aggregate([ { "$match": { "a": { "$in": [1,2,3] } }} ]) 因此,“不可能”在聚合管道中“调用”任何JavaScript函数,也不可能“传入”保存在system.js中的结果。“代码”需要“加载到客户端”,只有JavaScript引擎才能真正使用它 在聚合框架中,所有可用的“运算符”实际上都是本机编码的函数,而不是为mapReduce提供的“自由形式”JavaScript解释。因此,不用编写“JavaScript”,而是使用运算符本身: db.sample.aggregate([ { "$group": { "_id": null, "sqared": { "$sum": { "$multiply": [ "$a", "$a" ] }} }} ]) { "_id" : null, "sqared" : 14 } 因此,使用system.js中保存的函数所能做的事情是有限制的,很可能您想要做的是: 不允许,例如访问另一个集合中的数据 实际上并不需要,因为逻辑通常是自包含的 或者可能更好地以客户机逻辑或其他不同形式实现 我真正能想到的唯一实际用途是,有许多“mapReduce”操作无法以任何其他方式完成,并且有各种“共享”函数,它们宁愿存储在服务器上,也不愿在每次mapReduce函数调用中维护 但是,在聚合框架中使用mapReduce的90%原因通常是集合的“文档结构”选择不当,而且遍历文档进行搜索和分析“需要”JavaScript功能 因此,您可以在允许的约束下使用它,但在大多数情况下,您可能根本不应该使用它,而是修复了其他问题,这些问题让您认为您首先需要这个功能
# 1 楼答案
保存到} 运算符和^{} 等“JavaScript”处理语句使用,并可由
system.js
的任何函数都可供^{_id
值引用以及“样本”收集中插入的一些数据:
然后:
给出:
或与
$where
一起:但在“两者都不”的情况下,您不能使用全局变量,例如数据库
db
引用或其他函数。$where
和mapReduce
文档都包含关于您在这里可以做什么的限制的信息。所以,如果你认为你要做“在另一个集合中查找数据”之类的事情,那么你可以忘记它,因为它是“不允许的”每个MongoDB命令操作实际上都是对“引擎盖下”的“runCommand”操作的调用。但是,除非该命令实际上是在“调用JavaScript处理引擎”,否则它的用法就变得无关紧要了。无论如何,只有少数几个命令可以做到这一点,它们是
mapReduce
、group
或eval
,当然还有$where
的find操作聚合框架不以任何方式使用JavaScript。正如其他人所做的那样,你可能误解了这样一句话,它并没有达到你认为的效果:
也就是说,“没有在聚合管道内运行”,而是在将管道发送到服务器之前,对
.distinct()
调用的“结果”进行“评估”。就像使用外部变量一样:两者基本上都以相同的方式发送到服务器:
因此,“不可能”在聚合管道中“调用”任何JavaScript函数,也不可能“传入”保存在
system.js
中的结果。“代码”需要“加载到客户端”,只有JavaScript引擎才能真正使用它在聚合框架中,所有可用的“运算符”实际上都是本机编码的函数,而不是为
mapReduce
提供的“自由形式”JavaScript解释。因此,不用编写“JavaScript”,而是使用运算符本身:因此,使用system.js中保存的函数所能做的事情是有限制的,很可能您想要做的是:
我真正能想到的唯一实际用途是,有许多“mapReduce”操作无法以任何其他方式完成,并且有各种“共享”函数,它们宁愿存储在服务器上,也不愿在每次mapReduce函数调用中维护
但是,在聚合框架中使用mapReduce的90%原因通常是集合的“文档结构”选择不当,而且遍历文档进行搜索和分析“需要”JavaScript功能
因此,您可以在允许的约束下使用它,但在大多数情况下,您可能根本不应该使用它,而是修复了其他问题,这些问题让您认为您首先需要这个功能