Perform non-blocking eval reads in MongoDB

I figured out how to run javascript code on the MongoDB server, from a node.js client:

db.eval("function(x){ return x*10; }", 1, function (err, retval) {
  console.log('err: '+err);
  console.log('retval: '+retval);
});

And that works fine. But the docs say that db.eval() issues a write lock, so that nothing else can read or write to the database. I do not want that.

It also says that eval has no such limitation, but I do not know where to find it. From the way they're talking about it, it seems as if regular eval is only available in the mongo shell, and so not from the client side.

So: how can I run these stored procedures on the mongodb server without blocking everything?

you can pass an object with the field nolock set to true as an optional 3rd parameter to eval:

db.eval('function (x) {return x*10; }', [1], {nolock:true}, function(err, retval) {
     console.log('err: '+err);
     console.log('retval: '+retval);
});

Note that this prevents eval from setting an obligatory write-lock, but it doesn't prevent any operations inside your function from creating write-locks on their own.

Source: the documentation.

Note that the term "stored procedure" is wrong in this case. A stored procedure refers to code which is stored on the database itself and not delivered by the application layer. MongoDB can also do this utilizing the special collection db.system.js, but doing this is discouraged: http://docs.mongodb.org/manual/applications/server-side-javascript/#storing-functions-server-side

By the way: MongoDB wasn't designed for stored procedures. It is usually recommended to implement any advanced logic on the application layer. The practice to implement even trivial operations as stored procedures, like it is sometimes done on SQL databases, is discouraged.

This is this the way to store your functions on the Server Side and you call use it as shown below:

 db.system.js.save(    {      _id : "myAddFunction" , value : function (x,y)
{ return x +y;}    } );

db.system.js.find()

{ "_id" : "myAddFunction", "value" : function (x,y){ return x + y; } }


db.eval( "myAddFunction( 1 ,2)" )
3