Database Reference
In-Depth Information
The problem with this query is that the field references aren't restricted to a single
address. In other words, this query will match as long as one of the addresses is desig-
nated as “home” and one is in New York, but what you want is for both attributes to
apply to the same address. Fortunately, there's a query operator for this. To restrict
multiple conditions to the same sub-document, you use the $elemMatch operator. You
can properly satisfy the query like so:
db.users.find({addresses: {$elemMatch: {name: 'home', state: 'NY'}}})
Logically, you use $elemMatch only when you need to match two or more attributes in
a sub-document.
The only array operator left to discuss is the $size operator. This operator allows
you to query for an array by its size. For example, if you want to find all users with
exactly three addresses, you can use the $size operator like so:
db.users.find({addresses: {$size: 3}})
At the time of this writing, the $size operator doesn't use an index and is limited to
exact matches (you can't specify a range of sizes). 8 Therefore, if you need to perform
queries based on the size of an array, you should cache the size in its own attribute
within the document and update it manually as the array changes. For instance, you
might consider adding an address_length field to your user document. You could
then build an index on this field and issue all the range and exact match queries you
require.
J AVA S CRIPT
If you can't express your query with the tools described thus far, then you may need to
write some JavaScript. You can use the special $where operator to pass a JavaScript
expression to any query. Within a JavaScript context, the keyword this refers to the
current document. Let's take a contrived example:
db.reviews.find({$where: "function() { return this.helpful_votes > 3; }"}})
There's also an abbreviated form for simple expressions like this one:
db.reviews.find({$where: "this.helpful_votes > 3"}})
This query works, but you'd never want to use it because you can easily express it using
the standard query language. The problem is that JavaScript expressions can't use an
index, and they incur substantial overhead because they must be evaluated within a
JavaScript interpreter context. For these reasons, you should issue JavaScript queries
only when you can't express your query using the standard query language. If you do
find yourself needing JavaScript, try to combine the JavaScript expression with at least
one standard query operator. The standard query operator will pare down the result
set, reducing the number of documents that must be loaded into a JS context. Let's
take a quick example to see how this might make sense.
8
See https://jira.mongodb.org/browse/SERVER-478 for updates on this issue.
Search WWH ::




Custom Search