Does running server-side JavaScript have performance issues in MongoDB? Does V8 solve said performance issues?
Why does the MongoDB documentation recommended not using server-side functions?
When you ask about the viability of server-sided javascript, you first have to make clear what kind of server-sided javascript you are talking about. According to the documentation, there are four different kinds of server-sided code execution. Unfortunately they all are kind of hackish workarounds for situations where the native API is insufficient:
eval has the drawback that it only runs on one node. This greatly reduces its usefulness in a clustered environment. With sharded collections, it doesn't work at all!
By default, it also creates a global lock which makes the database completely unusable until the script has run. This can be prevented with the nolock
argument (unless the script itself does something which creates a global lock).
The answer by Sammaye also explains some serious security concerns.
It's really more of a test- and administration tool than something you should use for any regular operation.
In this case, the code isn't executed on the database, but rather on another independent process on one of the servers. This means that all the required data from other shards must be transfered to the server which runs the javascript code, no matter what's actually returned by the script.
It appears as another application to the mongodb server, so it can't do anything you couldn't also do from within your regular application. It's another test- and administration tool you shouldn't use in regular operation.
The $where operator in a find-command allows to pass a javascript function which is used to filter values. For most trivial cases, this is a lot less performant than what the other tools of the find query have to offer, especially because it can't make use of any indices.
When usage of $where can't be avoided, at least try to use some of the normal tools of the find-query to reduce the set of documents which need to be passed to the $where function.
MapReduce uses two javascript functions to create aggregated data. It used to be the primary data-mining tool for MongoDB, but most of its usual use-cases are now fulfilled by the much more user-friendly aggregation framework.
It also has the same drawback as $where: Unless you filter, you will have to run not one but at least two javascript functions for each document.
But MapReduce can at least run distributed and it can be parallelized.
Using Javascript is a last resort measure for very unusual queries which can not be made with the normal query language and which require access to too much data to be implemented in the application. When possible, do what you want to do with the specialized tools you have available or implement your logic on the application layer.
It is recommended within the documentation not to use stored JavaScript procedures within MongoDB.
I kind of still refuse to call it "server-side" since that denotes that it works "in" MongoDB which it does not, they are not stored procedures.
Anyway, by default JavaScript functions take global lock, which can be mitigated with nolock
and V8 (default since 2.4) can multithread; so it does seem as though this is usable but there are other problems:
Honestly the V8 change adds some awesomeness for Map Reduce and stuff but I would not say it changes much in terms of attempt to replace stored procedures with stored JavaScript functions.
As an added note: http://docs.mongodb.org/manual/reference/command/eval/#dbcmd.eval the warning box there should keep you away from trying this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With