eval

在本页面

Definition

  • eval
    • 从 3.0 版开始不推荐使用。

eval命令评估数据库服务器上的 JavaScript 函数。

eval命令的格式如下:

{
  eval: <function>,
  args: [ <arg1>, <arg2> ... ],
  nolock: <boolean>
}

该命令包含以下字段:

FieldTypeDescription
evalfunctionJavaScript 函数。
argsarray可选的。传递给 JavaScript 函数的参数数组。如果函数不带参数,则省略。
nolockboolean可选的。默认情况下,eval会在评估 JavaScript 函数之前获得全局写锁定。结果,在eval操作运行时,eval阻止了对数据库的所有其他读取和写入操作。在eval命令上将nolock设置为true,以防止eval命令在评估 JavaScript 之前获取全局写锁定。 nolock不会影响 JavaScript 代码本身中的操作是否需要写锁定。

JavaScript in MongoDB

尽管eval使用 JavaScript,但是大多数与 MongoDB 的交互都不使用 JavaScript,而是使用idiomatic driver作为交互应用程序的语言。

Behavior

您必须对副本集的primary成员运行eval。如果您尝试在secondary成员上运行eval,则 MongoDB 将返回错误。

Write Lock

默认情况下,eval在评估 JavaScript 函数时会采用全局写锁定。结果,在eval操作运行时,eval阻止了对数据库的所有其他读取和写入操作。

为了防止在评估 JavaScript 代码时获取全局写锁定,请使用eval命令,并且nolock设置为truenolock不会影响 JavaScript 代码中的操作是否带有写锁。

对于长时间运行的eval操作,请考虑将 eval 命令与nolock: true一起使用或使用其他服务器端代码执行选项

Sharded Data

您不能将evalsharded集合一起使用。通常,应避免在sharded clusters中使用eval;但是,可以将eval与未分片的集合和存储在sharded cluster中的数据库一起使用。

Access Control

在 2.6 版中进行了更改。

如果启用了授权,则必须有权访问所有资源上的所有操作才能运行eval。不建议提供这种访问权限,但是如果您的组织要求用户运行eval,请创建一个在anyResource上授予anyAction的角色。不要将此角色分配给任何其他用户。

Example

下面的示例使用eval执行增量并计算服务器上的平均值:

db.runCommand( {
      eval: function(name, incAmount) {
               var doc = db.myCollection.findOne( { name : name } );

               doc = doc || { name : name , num : 0 , total : 0 , avg : 0 };

               doc.num++;
               doc.total += incAmount;
               doc.avg = doc.total / doc.num;

               db.myCollection.save( doc );
               return doc;
            },
      args: [ "eliot", 5 ]
   }
);

函数中的db引用当前数据库。

mongo shell 提供了一个辅助方法db.eval() [1],因此您可以将以下内容表达为:

db.eval( function(name, incAmount) {
            var doc = db.myCollection.findOne( { name : name } );

            doc = doc || { name : name , num : 0 , total : 0 , avg : 0 };

            doc.num++;
            doc.total += incAmount;
            doc.avg = doc.total / doc.num;

            db.myCollection.save( doc );
            return doc;
         },
         "eliot", 5 );

如果要使用服务器的解释器,则必须运行eval。否则,mongo shell 的 JavaScript 解释器将评估直接 Importing 到该 shell 中的函数。

如果发生错误,则eval引发异常。以下无效函数使用变量x而不将其声明为参数:

db.runCommand(
               {
                 eval: function() { return x + x; },
                 args: [ 3 ]
               }
             )

该语句将导致以下异常:

{
   "errmsg" : "exception: JavaScript execution failed: ReferenceError: x is not defined near '{ return x + x; }' ",
   "code" : 16722,
   "ok" : 0
}
[1]mongoShell 程序中的帮助程序db.eval()包装了eval命令。因此,helper 方法具有一个 exception*共享基础命令的特性和行为:db.eval()方法不支持nolock选项。