Database Reference
In-Depth Information
{ _id: ObjectId("4d6574baa6b804ea563c459d"),
title: "Greenhouse flowers"
}
then a product belonging to both categories will look like this:
{ _id: ObjectId("4d6574baa6b804ea563ca982"),
name: "Dragon Orchid",
category_ids: [ ObjectId("4d6574baa6b804ea563c132a"),
ObjectId("4d6574baa6b804ea563c459d") ]
}
For efficient queries, you should index the array of category ID s:
db.products.ensureIndex({category_ids: 1})
Then, to find all products in the Epiphytes category, simply match against the
category_id field:
db.products.find({category_id: ObjectId("4d6574baa6b804ea563c132a")})
And to return all category documents related to the Dragon Orchid product, first get
the list of that product's category ID s:
product = db.products.findOne({_id: ObjectId("4d6574baa6b804ea563c132a")})
And then query the categories collection using the $in operator:
db.categories.find({_id: {$in: product['category_ids']}})
You'll notice that finding the categories requires two queries, whereas the product
search takes just one. This optimizes for the common case, as you're more likely to
search for products in a category than the other way around.
B.1.4
Trees
Like most RDBMS s, MongoDB has no built-in facility for tree representation and tra-
versal. Thus if you need tree-like behavior, then you've got to roll your own solution. I
presented a solution to the category hierarchy problem in chapters 5 and 6. The strat-
egy there was to store a snapshot of the category's ancestors within each category doc-
ument. This denormalization makes updates more complicated but greatly simplifies
reads.
Alas, the denormalized ancestor approach isn't great for all problems. Another
common tree scenario is the online forum, where hundreds of messages are fre-
quently nested many levels deep. There's too much nesting, and too much data, for
the ancestor approach to work well here. A good alternative is the materialized path .
Following the materialized path pattern, each node in the tree contains a path
field. This field stores the concatenation of each of the node's ancestor's IDs, and
root-level nodes have a null path because they have no ancestors. Let's flesh out an
example to see how this works. First, look at the comment thread in figure B.1. This
represents a few questions and answers in thread about Greek history.
Search WWH ::




Custom Search