翻译或纠错本页面

树结构建模: 物化路径

On this page

概述

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

这篇文章讲述使用一种在节点文档中保存完整的文档关系的方式来实现树结构建模。

范式

The Materialized Paths pattern stores each tree node in a document; in addition to the tree node, document stores as a string the id(s) of the node’s ancestors or path. Although the Materialized Paths pattern requires additional steps of working with strings and regular expressions, the pattern also provides more flexibility in working with the path, such as finding nodes by partial paths.

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

Tree data model for a sample hierarchy of categories.

下面是一个使用 物化路径 来建模的例子。在节点文档中的 path 字段保存了以逗号为分隔符的路径字符串。

db.categories.insert( { _id: "Books", path: null } )
db.categories.insert( { _id: "Programming", path: ",Books," } )
db.categories.insert( { _id: "Databases", path: ",Books,Programming," } )
db.categories.insert( { _id: "Languages", path: ",Books,Programming," } )
db.categories.insert( { _id: "MongoDB", path: ",Books,Programming,Databases," } )
db.categories.insert( { _id: "dbm", path: ",Books,Programming,Databases," } )
  • 你可以查询整个树的所有节点并按 path 排序:

    db.categories.find().sort( { path: 1 } )
    
  • 你可以在 path 字段上使用正则表达式来查询 Programming 的所有子代节点:

    db.categories.find( { path: /,Programming,/ } )
    
  • 你也可以查询到根节点 Books 的所有子代节点:

    db.categories.find( { path: /^,Books,/ } )
    
  • 你可以在 path 字段上创建索引:

    db.categories.createIndex( { path: 1 } )
    

    这个索引对某些查询的性能会有所提高:

    • 如果从根节点开始查询,(e.g. /^,Books,/) , path 字段上的索引会对提高查询性能有显著的作用。

    • 如果查询类似于 Programming 这些非根节点下面的子代节点, (e.g. /,Programming,/)由于这些被查询的节点可能在索引字符串的中部而导致全索引扫描。

      For these queries an index may provide some performance improvement if the index is significantly smaller than the entire collection.