TheTargetmobile
TheTargetmobile

Reputation: 33

What are the performance differences between MongoDB collection methods and database commands

While the post linked here answered the fundamental difference, is there a performance difference between the two? If I'm using a MongoDB backend, what are the tradeoffs between methods and commands, or are they really interchangeable (at least for update, insert, delete)?

Upvotes: 0

Views: 82

Answers (1)

Neil Lunn
Neil Lunn

Reputation: 151122

The general case is that either form is relatively interchangeable. Much as the answer in the post you reference addresses the fact that what you see in the mongo shell methods and also within the driver implementations is that the methods offered are really just wrappers around the underlying command methods, which even something like db.runCommand itself does to some extent.

So really, everything is just a means to an end to marshal a request into a BSON object to be processed on the system $cmd collection. The only real considerations come into the implmentation, which you might view as overhead but you most likely really should be doing those things anyway.

For example, you can dig into the .update() implementation in the mongo shell which will show "some" of the wrapping code. So a main snippet:

if (!wc)
    wc = this.getWriteConcern();

if ( this.getMongo().writeMode() != "legacy" ) {
    var bulk = this.initializeOrderedBulkOp();
    var updateOp = bulk.find(query);

    if (upsert) {
        updateOp = updateOp.upsert();
    }

    if (multi) {
        updateOp.update(obj);
    }
    else {
        updateOp.updateOne(obj);
    }

    try {
        result = bulk.execute(wc).toSingleResult();
    }
    catch( ex ) {
        if ( ex instanceof BulkWriteError || ex instanceof WriteCommandError ) {
            result = ex.toSingleResult();
        }
        else {
            // Other exceptions thrown
            throw ex;
        }
    }
}
else {
    this._validateUpdateDoc(obj);
    this.getMongo().update(this._fullName, query, obj,
                       upsert ? true : false, multi ? true : false );

    // enforce write concern, if required
    if (wc)
        result = this.runCommand("getLastError", wc instanceof WriteConcern ? wc.toJSON() : wc);
}

That is from a MongoDB 2.6 release. What you can see here is that this "helper" essentially tries to "wrap" the request arguments into a new styled "bulk" operation. Even though "singular" and not bulk, the intent here is make use of the "write concern" response that is offered.

With consideration to performance, the requests can be made without the "write concern" implementation which is essentially shown in the "legacy" implementation in the code with the call to "getLastError".

What this means is the calls themselves are essentially "fire and forget", and while you can explicitly set this level of "write concern" the general call to the method does not actually wait for the request itself. It is the "getLastError" call with the level of "write concern" that is implemented which actually "waits" for the request to process and returns the information such as what was "found", "modified", "inserted" or "deleted".

At the end of the day, you could issue raw commands or do your own implementation that did not take such things into consideration and is simply a fast "fire and forget" version of all your operations. But with that said, this is probably not really what you want to do in your application as you either want the "durability" that is offered or simply just otherwise "tune" the durability to your required level by setting the "write concern" as is appropriate to your case.

Also in terms of all the general "CRUD" operations with the general exception of "Read" or .find(), the "Bulk" operations give you the best performance boost by combining multiple requests as one "over the wire" request. That in itself and not having to await the response of each individual operation is the best performance boost you are going to get. So it does indeed look worth using as opposed "raw" commands by themselves.

Upvotes: 1

Related Questions