Mongodb 使用聚合管道、MapReduce或runCommand中存储的JavaScript函数

Mongodb 使用聚合管道、MapReduce或runCommand中存储的JavaScript函数,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,有没有办法在pipeline或mapreduce中使用另存为db.system.js.save(…)的用户定义函数 保存到system.js的任何函数都可供“JavaScript”处理语句(如运算符)使用,并且可由\u id值引用 db.system.js.save({ “_id”:“squareThis”, “value”:函数(a){返回a*a} }) 以及一些插入到“样本”集合中的数据: {u id:ObjectId(“55aafd2bacbed38e06f9eccf”),“a”:1}

有没有办法在pipeline或mapreduce中使用另存为
db.system.js.save(…)
的用户定义函数

保存到
system.js
的任何函数都可供“JavaScript”处理语句(如运算符)使用,并且可由
\u id
值引用

db.system.js.save({
“_id”:“squareThis”,
“value”:函数(a){返回a*a}
})
以及一些插入到“样本”集合中的数据:

{u id:ObjectId(“55aafd2bacbed38e06f9eccf”),“a”:1}
{u id:ObjectId(“55aafea6acbed38e06f9ecd0”),“a”:2}
{u id:ObjectId(“55aafeabababed38e06f9ecd1”),“a”:3}
然后:

db.sample.mapReduce(
函数(){
emit(null,squareThis(this.a));
},
功能(键、值){
返回Array.sum(值);
},
{“out”:{“inline”:1}
);
给出:

“结果”:[
{
“_id”:空,
“价值”:14
}
],
或使用
$where

db.sample.find(函数(){return squareThis(this.a)==9})
{u id:ObjectId(“55aafeabababed38e06f9ecd1”),“a”:3}
但在“两者都不”的情况下,您不能使用全局变量,例如数据库
db
reference或其他函数。
$where
mapReduce
文档都包含您可以在此处执行的操作的限制信息。因此,如果您认为您将要执行“在另一个集合中查找数据”之类的操作,那么您可以忘记它,因为它是“不允许的”

每个MongoDB命令操作实际上都是对“引擎盖下”的“runCommand”操作的调用。但是,除非该命令实际上是在“调用JavaScript处理引擎”,否则其用法就变得无关紧要了。无论如何,只有少数几个命令可以做到这一点,它们是
mapReduce
group
eval
,当然还有使用
$where
的查找操作


聚合框架不以任何方式使用JavaScript。正如其他人所做的那样,你可能会误解这样一句话,它并没有达到你所认为的效果:

db.sample.aggregate([
{“$match”:{
“a”:{“$in”:db.sample.distinct(“a”)}
}}
])
因此,这是在聚合管道中“不运行”,而是在管道发送到服务器之前,“评估”该
.distinct()
调用的“结果”。不管怎样,与使用外部变量一样:

var项目=[1,2,3];
db.sample.aggregate([
{“$match”:{
“a”:{“$in”:项目}
}}
])
两者基本上都以相同的方式发送到服务器:

db.sample.aggregate([
{“$match”:{
“a”:{“$in”:[1,2,3]}
}}
])
因此,“不可能”在聚合管道中“调用”任何JavaScript函数,也不可能“传入”保存在
system.js
中的结果。“代码”需要“加载到客户端”,只有JavaScript引擎才能真正使用它

使用聚合框架,所有可用的“操作符”实际上都是本机编码的函数,而不是为
mapReduce
提供的“自由形式”JavaScript解释。因此,您不用编写“JavaScript”,而是使用运算符本身:

db.sample.aggregate([
{“$组”:{
“_id”:空,
“sqared”:{“$sum”:{
“$multiply”:[“$a”,“$a”]
}}
}}
])
{u id:null,“sqared:14}
因此,对于保存在中的函数,您可以执行的操作存在限制,您希望执行的操作可能是:

  • 不允许,例如访问另一个集合中的数据
  • 实际上并不需要,因为逻辑通常是自包含的
  • 或者可能更好地用客户机逻辑或其他不同的形式实现
我能真正想到的唯一实际用途是,您有许多“mapReduce”操作,这些操作无法以任何其他方式完成,并且您有各种“共享”函数,这些函数只存储在服务器上,而不是在每次mapReduce函数调用中维护

但是,在聚合框架中使用mapReduce的90%的原因通常是集合的“文档结构”选择不当,并且遍历文档进行搜索和分析“需要”JavaScript功能

因此,您可以在允许的约束下使用它,但在大多数情况下,您可能根本不应该使用它,而是修复了导致您认为首先需要此功能的其他问题