使用ArangoDb/OrientDb进行分层数据模型和文档搜索:是正确的解决方案吗?

使用ArangoDb/OrientDb进行分层数据模型和文档搜索:是正确的解决方案吗?,orientdb,graph-databases,arangodb,document-database,nosql,Orientdb,Graph Databases,Arangodb,Document Database,Nosql,我正在开发一个文档管理软件,我正在评估一个用于存储和搜索数据的noSql数据库 当项目被组织在目录和子目录中时,软件就像一个文件系统 树的每个项可以有n个用于筛选和排序的属性 项目最终也可以通过父子关系以外的其他关系相互连接 项目数量可能相对较大,大约有数百万个,应用程序的杀手级功能必须是 使用过滤器检索数据和独立于数据库的属性排序时的costant性能 我需要3个关键特性: 获取文件夹的直接子项。对于每个文档属性,结果必须是可分页、可排序和可筛选的 获取文件夹的所有子目录以及子树的所有项。对于

我正在开发一个文档管理软件,我正在评估一个用于存储和搜索数据的noSql数据库

当项目被组织在目录和子目录中时,软件就像一个文件系统

树的每个项可以有n个用于筛选和排序的属性

项目最终也可以通过父子关系以外的其他关系相互连接

项目数量可能相对较大,大约有数百万个,应用程序的杀手级功能必须是 使用过滤器检索数据和独立于数据库的属性排序时的costant性能

我需要3个关键特性:

获取文件夹的直接子项。对于每个文档属性,结果必须是可分页、可排序和可筛选的

获取文件夹的所有子目录以及子树的所有项。对于每个文档属性,结果必须是可分页、可排序和可筛选的

获取文件夹的所有父级

我是noSql的新手,实际上我使用的是rdbms Sql Server,但我遇到了性能问题,以及文档属性的固定模式造成的所有限制。 我正在评估OrangoDb或OrientDb,因为我认为它的面向特性文档和面向图形可能是满足我的设计需求的最佳解决方案

你能帮我,给我一个建议,为这3个任务设计数据库和查询吗

注意。我需要查询结果返回一个数据集,其中每个属性都有一列:

Es. doc1: p1: v1, p2: v2
    doc2: p1: v1, p3: v3

result:
    name | p1 | p2 | p3
    doc1   v1   v2   null
    doc2   v1   null v3
我认为将一个项目设计为:

{ 
  "_id": "_myItemId",
  "name`enter code here`" : "Item1",
  "itemType": "root / folder / file"   
  "parentItemId": "",
  "properties" : [ 
    { name: "Property1", formatType: 0, formatMask: "", value: "Value1" }, 
    { name: "Property2", formatType: 0, formatMask: "", value: "Value2" }, 
    { name: "Property3", formatType: 0, formatMask: "", value: "Value3" }  
  ] 
}
对于能够解决上述3个关键特性的设计,您有什么建议吗


感谢使用图形数据库的方法,它与其他类型的dbms非常不同。可以使用边连接实体顶点,这是一个实体和另一个实体之间的直接链接。因此,首先,您不需要像在Sql或文档数据库中那样存储每个对象的parentItemId,而是只需要两个/三个或多个实体的特定数据;关系将由您在它们之间创建的边处理

OrientdDb有一个非常好的文档和一些示例来开始理解概念。教程页面:解释了图形的概念,并有一些很好的例子

在您的特定情况下,可以有两种实体类型:顶点、文件夹和文档,以及一条您称之为“从文档到文件夹的ChildOf”或“从文件夹到文档的包含”的边。然后,您可以执行许多查询来查找关系,甚至可以指定嵌套级别等

您可以通过以下步骤创建工作架构:

1创建类和边tpyes:

CREATE CLASS Document Extends V
CREATE CLASS Folder Extends V
CREATE CLASS ChildOf Extends E
2插入一些文件

INSERT INTO Document SET Title = 'Document 1', Name = '..'
INSERT INTO Document SET Title = 'Document 2', Name = '..'
INSERT INTO Document SET Title = 'Document 3', Name = '..'
3插入文件夹

INSERT INTO Folder SET Name = 'Folder 1'
INSERT INTO Folder SET Name = 'Folder 2'
4创建顶点之间的边关系

CREATE EDGE ChildOf FROM #<specify document rid here> TO #<specify folder rid here>
...
通过在两个文件夹之间设置相同的ChildOf edge,也可以将文件夹创建为另一个文件夹的子文件夹:

 CREATE EDGE ChildOf FROM #<specify children folder rid here> TO #<specify parent folder rid here>
...
5查询你的图表。使用expand和in运算符获取文件夹的直接子级:

Select expand(in('ChildOf')) From #<folder rid> Where ...
获取文件夹的所有子项,使用遍历查询遍历起始文件夹中的所有子项:

SELECT FROM (
     TRAVERSE out('ChildOf') FROM #<folder rid> WHILE $depth <= 3 //you can specify the maximum level of nesting
) where $depth > 0 //exclude the first element (the starting folder itself)
使用“遍历”和“在图形中”操作符获取文件夹的所有父级:

SELECT FROM (
         TRAVERSE in('ChildOf') FROM #<folder rid> 
    ) where $depth > 0 //exclude the first element (the starting folder itself)
//here you could filter only the "Folders"
where @class ='Folder'

你在O'Reilly雷达看到这个帖子了吗?我在ArangoDb中实现了2个集合,Items文档集合(包含文件夹和文件的信息)和ItemsParents边缘集合(包含项的父子关系)。我对自己的表现很失望,当然我做错了什么。。。我已经插入了大约100万个项目,简单计算项目的性能非常糟糕。。。需要30/40分钟。。AQL查询是:LET u=FOR Items IN Items RETURN item.\u key RETURN LENGTHu–我哪里做错了?如果您只想计算项目,而不需要它们的实际内容,则返回NULL而不是item.key更为合理。它不需要访问成员,更不用说移动数据。我正在处理一个类似的项目,您是否测试了以下答案对性能的影响@ClaudioThanks Stefano,我目前正在测试ArangoDb,但下一步是评估OrientDb。概念是一样的,ArangoDb和OrientDb是类似的。ArangoDb有一种专有语言,而OrientDb有一种类似sql的语言,你可以用一个你更喜欢的,我没有为他们做任何担保:我在做类似的项目,你测试过这个答案吗@克劳迪奥