在键值数据库中存储目录层次 struct /树(在我的例子中是MongoDB,但不是其中任何一种)的干净/高效的方法是什么?

例如树 struct

- Cars 
   + Audi 
   + BMW
      - M5
   + Ford
- Color
   + Red
      - Apple
      - Cherry
   + Purple
- Funny

我现在使用的方法是,每个对象都链接到其父对象

{ 
  dir: "red"
  parent-dir: "color"
}

这使得插入和重新排序树的任何方面非常高效/快速(例如,如果我想将Red及其所有子项移动到Cars目录).

但是,当我想要递归地删除给定目录的所有子目录及其子目录时,这种方法很糟糕.为了提高解析效率,我可以使用一个 struct

{ 
  dir: "red"
  children: "audi, bmw, ford"
}

{ 
  dir: "bmw"
  children: "m5"
}

但是如果我想修改这棵树,需要touch 和修改一大堆对象.

在KV存储中存储目录 struct 还有其他方法吗?

推荐答案

您现在使用的方法称为adjacency list model.

在(关系)数据库中存储分层数据的另一个模型是nested set model.是implementation in SQL databases is well known.另见this article for the modified preorder tree traversal algorithm.

一个非常简单的方法:你可以 for each 对象存储一个路径——有了这些,在NOSQL数据库中查询树应该很容易:

{ path: "Color", ... }
{ path: "Color.Red", ... }
{ path: "Color.Red.Apple", ... }
{ path: "Color.Red.Cherry", ... }

删除或重命名 node 时,必须更新某些路径.但总的来说,这种方法看起来很有希望.您只需保留一个特殊字符作为分隔符.存储空间开销应该可以忽略不计.

edit: this method is called 100

最后,这里是a comparison of different methods for hierarchical data in NOSQL databases.

Mongodb相关问答推荐

在MongoDB中使用explain()和查询时缺少winningPlan''''

MongoDB聚合匹配字符串字符

字段$set聚合导致错误美元($)前缀字段$concatArrays对于存储无效"

在MondoDB中:将对象数组从切片索引数组切片,并通过聚合推入数组

除非满足某个条件,否则Mongo是否按日期排序?

更新值导致错误 Golang MongoDB

避免在 MongoDB 聚合框架中使用 ISODate() 以便管道可以是纯 JSON

MongoDB shell:如何删除列表以外的所有集合

从 MongoDB 中的聚合结果中获取不同的值

Mongoose - $project 嵌套的对象数组到数组的根级别

无法让 Mongoose.js 子文档数组填充

mongodb:多键索引 struct ?

删除一对一和一对多引用 - Mongoose

如何使用python将csv数据推送到mongodb

字段类型在 MongoDB 索引中是否重要?

请按语法排序 Mongoid Scope

使用 Mongoid 和 Ruby 查询最近 30 天的日期范围?

Mongoose 连接认证失败

使用 C# 聚合 $lookup

用 MongoDB 中的属性表示多对多关系的最佳模型