在Aggregation管道,MapReduce或runCommand中使用存储的JavaScript函数

时间:2015-07-18 23:51:56

标签: mongodb mongodb-query aggregation-framework

有没有办法在管道或mapreduce中使用保存为db.system.js.save(...)的用户定义函数?

1 个答案:

答案 0 :(得分:12)

您保存到system.js的所有功能均可供" JavaScript" _id运算符和$where之类的处理语句可以被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

但是"不是" case可以使用全局变量,例如数据库$where引用或其他函数。 mapReducemapReduce文档都包含您在此处可以执行的操作限制的信息。因此,如果你认为你会做类似#34的事情;在另一个集合中查找数据",那么你可以忘记它,因为它是"不允许"。

每个 MongoDB命令操作实际上是对" runCommand"的调用。行动"引擎盖"无论如何。但除非该命令实际上正在做什么,否则调用JavaScript处理引擎"然后使用变得无关紧要。无论如何,执行此操作的命令只有groupeval$where,当然还有db.sample.aggregate([ { "$match": { "a": { "$in": db.sample.distinct("a") } }} ]) 的查找操作。

聚合框架以任何方式使用JavaScript。你可能会误会,正如其他人做过这样的陈述,这不符合你的想法:

.distinct()

这就是"没有在 " 聚合管道中运行,而是"结果"该var items = [1,2,3]; db.sample.aggregate([ { "$match": { "a": { "$in": items } }} ]) 来电的评估是"评估"在管道发送到服务器之前。就像外部变量完成一样:

db.sample.aggregate([
    { "$match": {
        "a": { "$in": [1,2,3] }
    }}
])

两者基本上都以相同的方式发送到服务器:

system.js

所以"不可能"到"打电话"聚合管道中的任何JavaScript函数,也没有任何一点是"传入"结果通常来自mapReduce中保存的内容。 "代码"需要被加载到客户端"并且只有JavaScript引擎才能实际执行任何操作。

使用聚合框架,所有"运算符"可用的实际上是本机编码的功能,而不是"自由形式"为db.sample.aggregate([ { "$group": { "_id": null, "sqared": { "$sum": { "$multiply": [ "$a", "$a" ] }} }} ]) { "_id" : null, "sqared" : 14 } 提供了JavaScript解释。因此,您不必编写" JavaScript",而是使用运算符本身:

<%= @articles.try(:suggestions) %>

因此,使用mapReduce中保存的函数可以执行的操作存在限制,您可能要做的是:

  • 不允许,例如访问其他集合中的数据
  • 不是真的需要,因为逻辑通常是自包含的
  • 或者可能更好地以客户端逻辑或其他形式实现

我能想到的唯一实际用途是你有很多&#34; mapReduce&#34;不能以任何其他方式完成的操作,并且您有各种各样的&#34;共享&#34;您希望存储在服务器上的函数,而不是在每个mapReduce函数调用中维护的函数。

但是再一次,mapReduce相对于聚合框架的90%原因通常是&#34;文档结构&#34;这些集合的选择很差,并且JavaScript功能是必需的#34;遍历文档进行搜索和分析。

所以你可以在允许的约束条件下使用它,但在大多数情况下你可能根本不应该使用它,而是修复导致你相信你需要这个功能的其他问题。