在 MongoDB 中运行服务器端 JavaScript 是否存在性能问题?V8 是否解决了上述性能问题?
为什么MongoDB 文档建议不要使用服务器端函数?
在 MongoDB 中运行服务器端 JavaScript 是否存在性能问题?V8 是否解决了上述性能问题?
为什么MongoDB 文档建议不要使用服务器端函数?
当您询问服务器端 javascript 的可行性时,您首先必须弄清楚您在谈论哪种服务器端 javascript。根据文档,有四种不同的服务器端代码执行。不幸的是,对于原生 API 不足的情况,它们都是一种骇人听闻的解决方法:
eval 的缺点是它只在一个节点上运行。这大大降低了它在集群环境中的实用性。使用分片集合,它根本不起作用!
默认情况下,它还会创建一个全局锁,使数据库在脚本运行之前完全不可用。这可以通过nolock
参数来防止(除非脚本本身做了一些创建全局锁的事情)。
Sammaye 的回答也解释了一些严重的安全问题。
它实际上更像是一个测试和管理工具,而不是您应该用于任何常规操作的工具。
在这种情况下,代码不会在数据库上执行,而是在其中一个服务器上的另一个独立进程上执行。这意味着来自其他分片的所有必需数据都必须传输到运行 javascript 代码的服务器,无论脚本实际返回什么。
它显示为 mongodb 服务器的另一个应用程序,因此它无法执行您在常规应用程序中也无法执行的任何操作。它是您不应该在常规操作中使用的另一种测试和管理工具。
find-command 中的 $where 运算符允许传递用于过滤值的 javascript 函数。对于大多数琐碎的情况,这比 find 查询的其他工具所提供的性能要低得多,尤其是因为它不能使用任何索引。
当无法避免使用 $where 时,至少尝试使用 find-query 的一些常规工具来减少需要传递给 $where 函数的文档集。
MapReduce 使用两个 javascript 函数来创建聚合数据。它曾经是 MongoDB 的主要数据挖掘工具,但它的大多数常用用例现在都由更加用户友好的聚合框架来实现。
它也有与 $where 相同的缺点:除非您进行过滤,否则您将不得不为每个文档运行不是一个而是至少两个 javascript 函数。
但是 MapReduce 至少可以分布式运行并且可以并行化。
使用 Javascript 是非常不寻常的查询的最后手段,这些查询无法使用普通查询语言进行,并且需要访问太多数据才能在应用程序中实现。如果可能,请使用可用的专用工具做您想做的事情,或在应用程序层实现您的逻辑。
文档中建议不要在 MongoDB 中使用存储的 JavaScript 过程。
我仍然拒绝称它为“服务器端”,因为这表示它可以“在”MongoDB 中工作,但它不是,它们不是存储过程。
无论如何,默认情况下,JavaScript 函数采用全局锁,这可以通过nolock
V8(自 2.4 开始的默认值)可以缓解多线程;所以看起来这似乎是可用的,但还有其他问题:
老实说,V8 的变化为 Map Reduce 和其他东西增加了一些令人敬畏的东西,但我不会说它在尝试用存储的 JavaScript 函数替换存储过程方面发生了很大变化。
作为补充说明:http ://docs.mongodb.org/manual/reference/command/eval/#dbcmd.eval那里的警告框应该让你远离尝试这个。