Databases Reference
In-Depth Information
To use $where in a query, write a JavaScript function that returns true or false (whether
that document matches the $where or not). So, suppose we only wanted to return re-
cords where the value of member[0].age and member[1].age are equal. We could do this
with:
> db.members.find({"$where" : function() {
... return this.member[0].age == this.member[1].age;
... }})
As you might imagine, $where gives your queries quite a lot of power. However, it is
also slow.
Behind the scenes
$where takes a long time because of what MongoDB is doing behind the scenes: when
you perform a normal (non- $where ) query, your client turns that query into BSON and
sends it to the database. MongoDB stores data in BSON, too, so it can basically compare
your query directly against the data. This is very fast and efficient.
Now suppose you have a $where clause that must be executed as part of your query.
MongoDB will have to create a JavaScript object for every document in the collection,
parsing the documents' BSON and adding all of their fields to the JavaScript objects.
Then it executes the JavaScript you sent against the documents, then tears it all down
again. This is extremely time- and resource-intensive.
Getting better performance
$where is a good hack when necessary, but it should be avoided whenever possible. In
fact, if you notice that your queries require lots of $where s, that is a good indication
that you should rethink your schema.
If a $where query is needed, you can cut down on the performance hit by minimizing
the number of documents that make it to the $where . Try to come up with other criteria
that can be checked without a $where and list that criteria first; the fewer documents
that are “in the running” by the time the query gets to the $where , the less time the
$where will take.
For example, suppose that we have the $where example given above, and we realize
that, as we're checking two members' ages, we are only for members with at least a
joint membership, maybe a family members:
> db.members.find({'type' : {$in : ['joint', 'family']},
... "$where" : function() {
... return this.member[0].age == this.member[1].age;
... }})
Now all single membership documents will be excluded by the time the query gets to
the $where .
 
Search WWH ::




Custom Search