On this page
eval
在本页面
Definition
eval
- 从 3.0 版开始不推荐使用。
eval命令评估数据库服务器上的 JavaScript 函数。
eval命令的格式如下:
{
eval: <function>,
args: [ <arg1>, <arg2> ... ],
nolock: <boolean>
}
该命令包含以下字段:
Field | Type | Description |
---|---|---|
eval |
function | JavaScript 函数。 |
args |
array | 可选的。传递给 JavaScript 函数的参数数组。如果函数不带参数,则省略。 |
nolock |
boolean | 可选的。默认情况下,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
设置为true
。 nolock
不会影响 JavaScript 代码中的操作是否带有写锁。
对于长时间运行的eval操作,请考虑将 eval 命令与nolock: true
一起使用或使用其他服务器端代码执行选项。
Sharded Data
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
}
See also