OPTIONS
翻译或纠错本页面

树结构建模: 嵌套集合

概述

MongoDB的数据具有 灵活的模式集合 本身没有对文档结构的规则性校验。 但是你建模时所作的决定会影响到应用程序的性能和数据库的处理能力。参见 数据建模理论 以更多的了解一些关于MongoDB数据建模全面介绍。

这篇文章讲述一种对子树查询优化的树结构建模方式。这种方式是以牺牲树结构的更新性能作为代价的。

范式

嵌套集合 模式对整个树结构进行一次深度优先的遍历。遍历时候对每个节点的压栈和出栈作为两个不同的步骤记录下来。然后每一个节点就是一个文档,除了节点信息外,文档还保存父节点的id以及遍历的两个步骤编号。压栈时的步骤编号保存到 left 字段里, 而出栈时的步骤编号则保存到 right 字段里。

让我们看一下下图表示的树形分类结构:

Example of a hierarchical data. The numbers identify the stops at nodes during a roundtrip traversal of a tree.

Example of a hierarchical data. The numbers identify the stops at nodes during a roundtrip traversal of a tree.

下面是一个使用 嵌套集合 来建模的例子:

db.categories.insert( { _id: "Books", parent: 0, left: 1, right: 12 } )
db.categories.insert( { _id: "Programming", parent: "Books", left: 2, right: 11 } )
db.categories.insert( { _id: "Languages", parent: "Programming", left: 3, right: 4 } )
db.categories.insert( { _id: "Databases", parent: "Programming", left: 5, right: 10 } )
db.categories.insert( { _id: "MongoDB", parent: "Databases", left: 6, right: 7 } )
db.categories.insert( { _id: "dbm", parent: "Databases", left: 8, right: 9 } )

你可以查询某个节点的子代节点:

var databaseCategory = db.categories.findOne( { _id: "Databases" } );
db.categories.find( { left: { $gt: databaseCategory.left }, right: { $lt: databaseCategory.right } } );

使用 嵌套集合 模式对查询子树类的操作而言是个快速高效的方案。然而在修改树结构时效率却相对较低。因此这个模式适合于那些树结构不经常会改变的场景。