mongodb服务器端javascript实际上是客户端?

时间:2016-05-18 10:34:10

标签: javascript mongodb server-side mongo-shell

我有大量文档,我想提取一些统计数据。它需要每15分钟定期执行一次。

大多数统计数据都是基于文档大小的,因此我需要获取文档并计算其大小。

我的统计数据的输出只是一行,包含一些关于文档大小的统计信息。 (我不是整个集合,只是它的一部分,所以我不能使用mongodb提供的集合统计数据)

我想要的是在服务器端执行此操作,并避免将所有文档传输到客户端,(因为我需要计算大小)。

我正在使用mongo shell执行它,确保我连接到辅助服务器,并且此 mongo shell始终在远程计算机上运行,因此这是避免传输所有文档的主要原因通过网络。

在阅读mongo shell文档后,我预计它将被执行"服务器端"正如它所声明的那样,但它并没有以这种方式工作,而是在与mongo shell相同的机器上执行(在我看来,它比服务器端更像客户端)。

我正在粘贴代码的摘录,以防它有用:

db.cache.find(query).forEach(function(obj) {

        var curr = Object.bsonsize(obj); 

        if(stats.max < curr) {
            stats.max = curr;
            stats.maxid = obj._id;
        } 
        if(stats.min > curr) {
            stats.min = curr;
        } 
        stats.count++;
        stats.total += curr;

        stats.avg = stats.total/stats.count;
    })

如果我在本地执行mongo shell并且在远程执行的mongo shell中执行超过1分钟,则需要3-4秒。

如何使这个服务器端javascript成为真正的服务器端执行?

更新

总结答案中提到的选项:

  • 使用system.js集合+ db.eval:我不能使用它,因为eval已被弃用,但eval也需要在主服务器上运行,而且我有在辅助设备上运行它。

  • 使用system.js集合+ loadServerScripts:它在mongo shell计算机中执行javascript代码,这是&#34;客户端&#34;。

  • cron job:我需要在特定节点上运行它,并且由于master可能会更改为另一个节点,我最终可以针对主节点运行它,我应该避免。但是,我不允许这样做,其中一个要求是在远程shell上运行它。 (有几个像这样的dbs需要这种统计数据,并且更容易只在一个地方使用它)。

1 个答案:

答案 0 :(得分:1)

您可以将js代码存储为一种存储过程

As per this article您可以将js存储为系统调用:

 db.system.js.save({_id: "sum", value: function (x, y) { return x + y; }});

然后称之为:

db.eval("return sum(2, 3);");
  

当eval被折旧时 - 没有时间设置它将被禁用see here

db.loadServerScripts();
sum(3,2) 

额外文档here

eval的其他解决方案是让cron job调用本地服务器上的javascript文件