Navigation
This version of the manual is no longer supported.

eval

eval

The eval command evaluates JavaScript functions on the database server and has the following form:

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

The command contains the following fields:

Fields:
  • function (JavaScript) –

    A JavaScript function.

    The function may accept no arguments, as in the following example:

    function () {
      // ...
    }
    

    The function can also accept arguments, as in the following example:

    function (arg1, arg2) {
       // ...
    }
    
  • arguments – A list of arguments to pass to the JavaScript function if the function accepts arguments. Omit if the function does not take arguments.
  • args (array) – An array of corresponding arguments to the function. Omit args 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.

Consider the following example which 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 shell also provides a helper method db.eval(), 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 );

The db.eval() method does not support the nolock option.

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. Consider the following invalid function that 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:

{
   "errno" : -3,
   "errmsg" : "invoke failed: JS Error: ReferenceError: x is not defined nofile_b:1",
   "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.
  • eval also takes a JavaScript 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.