5.2. 树形结构模型

具有父节点的树形结构模型

上图结构可以用父引用来表示:

db.categories.insertMany([
  { "_id": "MongoDB", "parent": "Databases" },
  { "_id": "dbm", "parent": "Databases" },
  { "_id": "Databases", "parent": "Programming" },
  { "_id": "Languages", "parent": "Programming" },
  { "_id": "Programming", "parent": "Books" },
  { "_id": "Books", "parent": null }
])
  • 检索节点的父节点:
    db.categories.findOne( { _id: "MongoDB" } ).parent
    
  • 可以在父字段上创建索引以启用父节点的快速搜索:
    db.categories.createIndex( { parent: 1 } )
    
  • 可以通过父字段查询找到其直接子节点:
    db.categories.find( { parent: "Databases" } )
    
  • 检索子树,可以参考: $graphLookup (opens new window).

具有子节点的树形结构模型

db.categories.insertMany([
  { "_id": "MongoDB", "children": [] },
  { "_id": "dbm", "children": [] },
  { "_id": "Databases", "children": ["MongoDB", "dbm"] },
  { "_id": "Languages", "children": [] },
  { "_id": "Programming", "children": ["Databases", "Languages"] },
  { "_id": "Books", "children": ["Programming"] }
])
  • 检索节点的 children:
    db.categories.findOne( { _id: "Databases" } ).children
    
  • 可以在 children 字段上创建索引以启用子节点的快速搜索:
    db.categories.createIndex( { children: 1 } )
    
  • 可以在 children 字段中查询节点,以找到其父节点及其兄弟节点:
    db.categories.find( { children: "MongoDB" } )
    

具有祖先的树形结构模型

db.categories.insertMany([
  {
    "_id": "MongoDB",
    "ancestors": ["Books", "Programming", "Databases"],
    "parent": "Databases"
  },
  {
    "_id": "dbm",
    "ancestors": ["Books", "Programming", "Databases"],
    "parent": "Databases"
  },
  {
    "_id": "Databases",
    "ancestors": ["Books", "Programming"],
    "parent": "Programming"
  },
  {
    "_id": "Languages",
    "ancestors": ["Books", "Programming"],
    "parent": "Programming"
  },
  { "_id": "Programming", "ancestors": ["Books"], "parent": "Books" },
  { "_id": "Books", "ancestors": [], "parent": null }
])
  • 检索节点的祖先或路径的查询是快速而直接的:
    db.categories.findOne({ "_id": "MongoDB" }).ancestors
    
  • 可以在 ancestors 字段上创建索引,以启用祖先节点的快速搜索:
    db.categories.createIndex({ "ancestors": 1 })
    
  • 可以通过 ancestors 字段查询查找其所有后代:
    db.categories.find({ "ancestors": "Programming" })
    

具有实体化路径的树形结构模型

db.categories.insertMany([
  { "_id": "Books", "path": null },
  { "_id": "Programming", "path": ",Books," },
  { "_id": "Databases", "path": ",Books,Programming," },
  { "_id": "Languages", "path": ",Books,Programming," },
  { "_id": "MongoDB", "path": ",Books,Programming,Databases," },
  { "_id": "dbm", "path": ",Books,Programming,Databases," }
])
  • 可以查询以检索整个树,并按字段路径排序:
    db.categories.find().sort( { path: 1 } )
    
  • 可以在 path 字段上使用正则表达式来查找 Programming 的后代
    db.categories.find( { path: /,Programming,/ } )
    
  • 可以检索 Books 的后代,其中 Books 也位于层次结构的最高级别:
    db.categories.find( { path: /^,Books,/ } )
    
  • 要在 path 字段上创建索引,请使用以下调用:
    db.categories.createIndex( { path: 1 } )
    

具有嵌套集的树形结构模型

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 }
]);

可以查询以检索节点的后代:

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