Search code examples
javascriptnode.jsmongodbnode-mongodb-native

How to create global objects in MongoDB's V8 engine to be accessible via db.eval?


I'm trying to use MongoDB server-side JavaScript in my nodejs/node-mongodb-native project and just interested how could I save my custom functions in global context of MongoDB and get access to them from db.eval script?

Let's say I have the following unit function:

var myDocumentUtils = {
    doStuff: function (doc) {
       // do stuff with doc ...
       return doc;      
    }
}

And I have the following JavaScript function stored in db.system.js collection:

function processDocument (id) {
    var doc = db.myCollection.findOne({ _id : ObjectId(id)});

    doc = myDocumentUtils.doStuff(doc);   // need access to global myDocumentUtils object     
    db.myCollection.save(doc);

    return doc;
};

I execute processDocument function from my nodejs application like the following:

db.eval('processDocument(54382cb3233283cd3331ca1d)', function (err, doc) {
    if (err) throw err;       
});

So my question is how to save myDocumentUtils in global MongoDB V8 context to be accessible in db.eval function?


Solution

  • Add the second parameter to processDocument as below:

    function processDocument (id, myDocumentUtils) {
        var doc = db.myCollection.findOne({ _id : ObjectId(id)});
    
        doc = myDocumentUtils.doStuff(doc);   // need access to global myDocumentUtils object     
        db.myCollection.save(doc);
    
        return doc;
    };
    

    Then write db.eval() like this way:

    db.eval(function() {
        return processDocument.apply(this, arguments);
    }, "54382cb3233283cd3331ca1d", myDocumentUtils);
    

    For your environment, you can add the call back just behind the last parameter myDocumentUtils.


    APPEND ---------------------

    store below tow functions into db.system.js :

    function getMyDocumentUtils() {
        return myDocumentUtils = {
                doStuff: function (doc) {
                   // do stuff with doc ...
                   return doc;      
                }
            };
    }
    
    function processDocument (id) {
        var doc = db.myCollection.findOne({ _id : ObjectId(id)});
    
        var myDocumentUtils = getMyDocumentUtils(); // added line
    
        doc = myDocumentUtils.doStuff(doc);   // need access to global myDocumentUtils object     
        db.myCollection.save(doc);
    
        return doc;
    };
    

    Then call db.eval() as your original style.