用于分层数据的Mongoose Schema,如文件夹>子文件夹>文件

jsD*_*ger 4 mongoose

我们如何为文件系统创建分层模式

var Folder = new Schema({

  'name' : String,
  'isFile' : Number,
  'children' : [Folder]
});
Run Code Online (Sandbox Code Playgroud)

我们可以这样做吗?

小智 8

您使用的架构将子文件夹嵌入父项中.这可能会奏效,但它有一些问题.

首先,每个文件夹文档的大小可能会变得非常大,具体取决于文件系统的大小,并且您可能会遇到大小限制的问题.

另一个问题是,直接查找不在顶层的文档非常困难.

更好的解决方案是将父/子关系存储为引用.

var Folder = new Schema({
    name: String,
    isFile: Boolean,
    parent: {
      type: Schema.Types.ObjectId,
      ref: 'Folder'
    },
    children: [{
      type: Schema.Types.ObjectId,
      ref: 'Folder'
    }]
});
Run Code Online (Sandbox Code Playgroud)

ref属性只是指示哪个Collection/Model mongoose应该查找引用的文档,所以如果你查询它就可以找到它.在这种情况下,我们引用父文件夹,它是一个文件夹,以及一个孩子列表,它们也是文件夹类型的文件.

存储对父对象的引用允许您轻松遍历树,对子对象的引用允许您从上到下生成树.

您可以使用populateMongoose 的功能从引用中提取详细信息.有关人口和参考的更多信息,请参阅Mongoose文档.


NB我换isFile了一个Boolean字段因为我假设你试图存储是/否值?


Eze*_*lla 6

有一些文档化的方法用于在MongoDB集合上存储分层数据,我在下面引用:

  1. 儿童参考
  2. 家长参考
  3. 一系列祖先
  4. 物化路径
  5. 嵌套集

您的选择将主要取决于您打算如何查询数据,每种方法都有自己的优缺点.如果需要,您可以一次性通过多种方法存储分层数据,但保持更新非常重要.为此,我建议使用mongoose插件.

我最喜欢的选择是物化路径,因为它在处理路径时提供了更大的灵活性,例如通过部分路径查找节点.

我引用MongoDB文档中的一个例子:

以下示例使用物化路径对树进行建模,将路径存储在字段路径中; 路径字符串使用逗号作为分隔符:

{ _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," }
Run Code Online (Sandbox Code Playgroud)
  1. 您可以查询以检索整个树,按字段路径排序:
Model.find().sort( { path: 1 } )
Run Code Online (Sandbox Code Playgroud)
  1. 您可以在路径字段上使用正则表达式来查找编程的后代:
Model.find( { path: /,Programming,/ } )
Run Code Online (Sandbox Code Playgroud)
  1. 您还可以检索Books的后代,其中Books也位于层次结构的最顶层:
Model.find( { path: /^,Books,/ } )
Run Code Online (Sandbox Code Playgroud)
  1. 您可能想要检索Books的直接子项:
Model.find( { path: /,Books,$/ } )
Run Code Online (Sandbox Code Playgroud)

阅读更多关于文档链接的内容,关于索引"路径"字段以获得更好的性能.

任何这些方法都可以由您自己或通过mongoose插件实现,您可以通过在http://plugins.mongoosejs.com上搜索"tree"来找到它们.