Database Reference
In-Depth Information
This works, but there are limits to searching for an exact match. For one, you might
not know how to spell a given user's name. In this case, you'll want some way of query-
ing for a partial match. Suppose you know that the user's last name starts with
Ba
. In
SQL
, you could use a
LIKE
condition to represent this query:
SELECT * from users WHERE last_name LIKE 'Ba%'
The semantic equivalent in MongoDB is a regular expression:
db.users.find({last_name: /^Ba/})
As with an
RDBMS
, a prefix search like this one can take advantage of an index.
2
When it comes to marketing to your users, you'll most likely want to target ranges
of users. For instance, if you wanted to get all users residing in Upper Manhattan, you
could issue this range query on a user's
ZIP
code:
db.users.find({'addresses.zip': {$gte: 10019, $lt: 10040}})
Recall that each user document contains an array of one or more addresses. This
query will match a user document if any
ZIP
code among those addresses falls within
the range specified. To make this query efficient, you'll want an index defined on
addresses.zip
.
Targeting users by location probably isn't the most effective way to generate con-
versions. Users can be much more meaningfully grouped by what they've purchased,
which in this case requires a two-step query: you first need to get a set of orders based
on a particular product, and once you have the orders, you can query for the associ-
ated users.
3
Suppose you want to target all users who've purchased the large wheelbar-
row. Again you use MongoDB's dot notation to reach into the
line_items
array and
search for a given
SKU
:
db.orders.find({'line_items.sku': "9092")
You can also imagine wanting to limit this result set to orders made within a certain
time frame. If so, you can easily add a query condition that sets a minimum order date:
db.orders.find({'line_items.sku': "9092",
'purchase_date': {$gte: new Date(2009, 0, 1)}})
Assuming these queries are issued frequently, you'll want a compound index ordered
first by
SKU
and second by date of purchase. You can create such an index like so:
db.orders.ensureIndex({'line_items.sku': 1, 'purchase_date': 1})
When you query the
orders
collection, all you're looking for is a list of user
ID
s. Thus,
you have an opportunity to be more efficient by using a projection. In the following
code snippet, you first specify that you want the
user_id
field only. You then
2
If you're not familiar with regular expressions, take note: the regular expression
/^Ba/
can be read as “the
beginning of the line followed by a
B
followed by an
a
.”
3
If you're coming from a relational database, the inability here to issue a JOIN query across orders and users
might bother you, but try not to let it. It's common to perform this sort of client-side join with MongoDB.