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

2024-02-01

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


您保存到的任何函数system.js可供“JavaScript”处理语句使用,例如$where http://docs.mongodb.org/manual/reference/operator/query/where/运算符和mapReduce http://docs.mongodb.org/manual/reference/command/mapReduce/并且可以参考_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 }

Then:

db.sample.mapReduce(
    function() {
       emit(null, squareThis(this.a));
    },
    function(key,values) {
        return Array.sum(values);
    },
    { "out": { "inline": 1 } }
 );

Gives:

   "results" : [
            {
                    "_id" : null,
                    "value" : 14
            }
    ],

Or with $where:

db.sample.find(function() { return squareThis(this.a) == 9 })
{ "_id" : ObjectId("55aafeabacbed38e06f9ecd1"), "a" : 3 }

但在“两种”情况下,您都可以使用数据库等全局变量db参考或其他功能。两个都$where and mapReduce文档包含您在此处可以执行的操作的限制信息。因此,如果您认为要执行“在另一个集合中查找数据”之类的操作,那么您可以忘记它,因为它是“不允许的”。

EveryMongoDB 命令操作实际上是无论如何,“在幕后”调用“runCommand”操作。但除非该命令实际执行的操作是“调用 JavaScript 处理引擎”,否则用法就变得无关紧要。无论如何,只有几个命令可以执行此操作,即mapReduce, group or eval,当然还有查找操作$where.


聚合框架的作用是not以任何方式使用 JavaScript。您可能会误解,就像其他人做了这样的声明一样,它并没有起到您认为的作用:

db.sample.aggregate([
    { "$match": {
        "a": { "$in": db.sample.distinct("a") }
    }}
])

所以那就是“没有运行inside"聚合管道,而是其“结果”.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 引擎才能真正用它做任何事情。

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

db.sample.aggregate([
    { "$group": {
        "_id": null,
        "sqared": { "$sum": {
           "$multiply": [ "$a", "$a" ]
        }}
    }}
])

{ "_id" : null, "sqared" : 14 }

因此,您可以使用保存在中的函数执行的操作受到限制系统.js http://docs.mongodb.org/manual/tutorial/store-javascript-function-on-server/,您想做的事情很可能是:

  • 不允许,例如从另一个集合访问数据
  • 并不是真正需要的,因为无论如何逻辑通常都是自包含的
  • 或者可能更好地以客户端逻辑或其他不同的形式实现

我真正能想到的唯一实际用途是,您有许多无法以任何其他方式完成的“mapReduce”操作,并且您有各种“共享”功能,您宁愿将其存储在服务器上,也不愿在每个功能中维护它们。调用mapReduce函数。

但话又说回来,mapReduce 超过聚合框架的 90% 原因通常是集合的“文档结构”选择不当,并且“需要”JavaScript 功能来遍历文档进行搜索和分析。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在聚合管道、MapReduce 或 runCommand 中使用存储的 JavaScript 函数 的相关文章

随机推荐