【问题标题】:mongodb server-side javascript is client-side actually?mongodb服务器端javascript实际上是客户端吗?
【发布时间】:2016-05-18 10:34:10
【问题描述】:

我有大量文档,我想从中提取一些统计数据。它需要每 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 大约需要 3-4 秒,而在远程执行的 mongo shell 中需要超过 1 分钟。

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

更新:

总结答案中提到的选项:

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

  • 使用system.jscollection + loadServerScripts:它在mongo shell机器中执行javascript代码,也就是“客户端”。

  • cron 作业:我需要在特定节点上运行它,并且由于 master 可能会更改为另一个节点,我最终可以针对 master 运行它,我应该避免这样做。而且,我不允许这样做,要求之一是在远程 shell 上运行它。 (有几个像这样的数据库需要这种统计信息,并且只在一个地方拥有它更容易保持)。

【问题讨论】:

  • ssh 到 mongo 服务器,在那里打开 mongo shell 并执行代码
  • REPL 中的 js 显然在 REPL 进程运行的同一台机器上执行。直接在 mongodb 服务器上运行 REPL。
  • 无法 ssh 到 mongo 服务器。这是一个生产环境,我永远没有权限这样做:(
  • 如何直接在 mongodb 服务器上运行 REPL?

标签: javascript mongodb server-side mongo-shell


【解决方案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 文件

【讨论】:

  • 感谢您的回复。使用 eval 时,我收到此警告:“警告:不推荐使用 db.eval”。在不使用 eval 的情况下还有其他方法吗?
  • 使用 loadServerScripts,它是在 mongo shell 机器中执行的,所以我又遇到了和以前一样的问题 :(
  • @richardtz 因为您可以访问 mongo 控制台 - 那么您可以发出:db.loadServerScripts(); - 我说的对吗?或者你打算有一个用 cron 调用的脚本?
  • 不确定 mongo 控制台是什么意思。我正在使用 mongo shell 来执行我的脚本。这个 mongo shell 在远程机器上运行。如果我使用 eval,那么我的代码将在服务器中执行 -> 很好但已弃用。如果使用 loadServerScripts,那么我的代码将在远程机器而不是服务器中执行。
  • @richardtz -eval 的其他解决方案是让cron job 在服务器上本地调用一个 javascript 文件
猜你喜欢
  • 2018-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 2011-08-07
  • 2010-09-14
  • 1970-01-01
相关资源
最近更新 更多