Model Tree Structures with Nested Sets
Overview
This document describes a data model that describes a tree like structure that optimizes discovering subtrees at the expense of tree mutability.
Pattern
The Nested Sets pattern identifies each node in the tree as stops in
a round-trip traversal of the tree. The application visits each node
in the tree twice; first during the initial trip, and second during
the return trip. The Nested Sets pattern stores each tree node in a
document; in addition to the tree node, document stores the ID of
node's parent, the node's initial stop in the left
field, and its
return stop in the right
field.
Consider the following hierarchy of categories:
The following example models the tree using Nested Sets:
db.categories.insertMany( [ { _id: "Books", parent: 0, left: 1, right: 12 }, { _id: "Programming", parent: "Books", left: 2, right: 11 }, { _id: "Languages", parent: "Programming", left: 3, right: 4 }, { _id: "Databases", parent: "Programming", left: 5, right: 10 }, { _id: "MongoDB", parent: "Databases", left: 6, right: 7 }, { _id: "dbm", parent: "Databases", left: 8, right: 9 } ] )
You can query to retrieve the descendants of a node:
var databaseCategory = db.categories.findOne( { _id: "Databases" } ); db.categories.find( { left: { $gt: databaseCategory.left }, right: { $lt: databaseCategory.right } } );
The Nested Sets pattern provides a fast and efficient solution for finding subtrees but is inefficient for modifying the tree structure. As such, this pattern is best for static trees that do not change.