OPTIONS

eval

eval

The eval command evaluates JavaScript functions on the database server.

If authentication is enabled, you must have access to all actions on all resources in order to run eval. Providing such access is not recommended, but if your organization requires a user to run eval, create a role that grants anyAction on anyResource. Do not assign this role to any other user.

The eval command has the following form:

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

The command contains the following fields:

Field Type Description
eval function A JavaScript function.
args array Optional. An array of arguments to pass to the JavaScript function. Omit if the function does not take arguments.
nolock boolean Optional. By default, eval takes a global write lock before evaluating the JavaScript function. As a result, eval blocks all other read and write operations to the database while the eval operation runs. Set nolock to true on the eval command to prevent the eval command from taking the global write lock before evaluating the JavaScript. nolock does not impact whether operations within the JavaScript code itself takes a write lock.

JavaScript in MongoDB

Although eval uses JavaScript, most interactions with MongoDB do not use JavaScript but use an idiomatic driver in the language of the interacting application.

Behavior

The following example uses eval to perform an increment and calculate the average on the server:

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 ]
   }
);

The db in the function refers to the current database.

The mongo shell provides a helper method db.eval() [1], so you can express the above as follows:

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 );

If you want to use the server’s interpreter, you must run eval. Otherwise, the mongo shell’s JavaScript interpreter evaluates functions entered directly into the shell.

If an error occurs, eval throws an exception. The following invalid function uses the variable x without declaring it as an argument:

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

The statement will result in the following exception:

{
   "errmsg" : "exception: JavaScript execution failed: ReferenceError: x is not defined near '{ return x + x; }' ",
   "code" : 16722,
   "ok" : 0
}

Warning

  • By default, eval takes a global write lock before evaluating the JavaScript function. As a result, eval blocks all other read and write operations to the database while the eval operation runs. Set nolock to true on the eval command to prevent the eval command from taking the global write lock before evaluating the JavaScript. nolock does not impact whether operations within the JavaScript code itself takes a write lock.

  • Do not use eval for long running operations as eval blocks all other operations. Consider using other server side code execution options.

  • You can not use eval with sharded data. In general, you should avoid using eval in sharded cluster; nevertheless, it is possible to use eval with non-sharded collections and databases stored in a sharded cluster.

  • With authentication enabled, eval will fail during the operation if you do not have the permission to perform a specified task.

    Changed in version 2.4: You must have full admin access to run.

Changed in version 2.4: The V8 JavaScript engine, which became the default in 2.4, allows multiple JavaScript operations to execute at the same time. Prior to 2.4, eval executed in a single thread.

[1]The helper db.eval() in the mongo shell wraps the eval command. Therefore, the helper method shares the characteristics and behavior of the underlying command with one exception: db.eval() method does not support the nolock option.
ON THIS PAGE