Arangodb:在结构树中引用叶子的最佳建模策略

时间:2016-02-08 22:05:40

标签: arangodb

给出修复3级深度树结构,如

集合:树

{
    "name": "Level 1",
    "children": [{
        "name": "Level 1.1",
        "children": [{
            "name": "Level 1.1.1"
        }, {
            "name": "Level 1.1.2"
        }]
    }, {
        "name": "Level 1.2",
        "children": [{
            "name": "Level 1.2.1"
        }]
    }]
}

在另一个集合中引用了一个" leaf"节点:

收集" person"

{
  "name": {
    "first": "John",
    "last": "Doe"
  },
  "linkToLeaf": "<need to reference a leaf node. e.g. 'Level 1.2.1'>"
}

并且需要查询数据:

  1. 渲染树,以便管理员用户可以组织层次结构(基本CRUD页面)
  2. 在某些地方显示面包屑&#34;您所在的位置:1级&gt;等级1.2&gt;等级1.2.1&#34;
  3. 建立与叶节点&#34;
  4. 的链接

    使用arangodb,对数据进行建模的最佳方法是什么?使用图形,简单的JSON文档,两者的混合,还有什么?

    我正在开发一个新项目,我们希望跳转到NoSQL但是来自传统RDBMS的背景我只是使用递归连接对树进行建模,因此只需引用&#34; leaf节点&#34;使用它的主键。

    不确定怎么做Arangodb ......

1 个答案:

答案 0 :(得分:3)

有几点应该对您的数据模型产生影响:

  • 和常规数据库一样,联接不是免费的。将来自多个集合的数据聚合到一个文档中可能会有所帮助。
  • 取决于您想要更新的内容,使用深度结构化的文档可能会变得具有挑战性并且难以阅读AQL。

在你的例子中,你展示了一些看似非常相似的东西,像分形一样嵌套。 你可以为shure做这个平面,并做你通过图遍历嵌套的东西。 这对于客户端的代码来说可能是有益的,并且您不仅会被绑定到固定数量的层; Graph traversals产生一种非常好的行为,你甚至可以更深层次地进行动态迭代。

新的ArangoDB模式匹配遍历可能如下所示:

db._create("names");
db.names.save({_key: "Level1"});
db.names.save({_key: "Level1.1"});
db.names.save({_key: "Level1.1.1"});
db.names.save({_key: "Level1.1.2"});
db.names.save({_key: "Level1.1.3"});
db.names.save({_key: "Level1.2"});
db.names.save({_key: "Level1.2.1"});

db._createEdgeCollection("nameEdges")
db.nameEdges.save("names/Level1",   "names/Level1.1",   {layer: 0})
db.nameEdges.save("names/Level1.1", "names/Level1.1.1", {layer: 1})
db.nameEdges.save("names/Level1.1", "names/Level1.1.2", {layer: 1})
db.nameEdges.save("names/Level1.1", "names/Level1.1.3", {layer: 1})
db.nameEdges.save("names/Level1",   "names/Level1.2",   {layer: 0})
db.nameEdges.save("names/Level1.2", "names/Level1.2.1", {layer: 1})

db._create("persons")
db.persons.save({_key: "adam_ant", details: {cname: "adam", lname: "ant"}})
db.persons.save({_key: "david_bowie", details:
    {cname: "david", lname: "bowie"}})

db._createEdgeCollection("nameToPersons")
db.nameToPersons.save("names/Level1", "persons/adam_ant",
    {himself: true})
db.nameToPersons.save("names/Level1.2", "persons/david_bowie",
    {alien: true})

递归到结构:

db._query("FOR v IN 1..3 OUTBOUND 'names/Level1' nameEdges RETURN v"
     ).toArray()

连接人;我们向他们展示顶点边缘路径

db._query("FOR v, e, p IN 1..4 OUTBOUND 'names/Level1' " +
          "nameEdges,nameToPersons " +
          "RETURN {v:v, e:e, p:p}").toArray()

您可以对顶点路径的任意属性进行shure过滤:

db._query("FOR v, e, p IN 1..4 OUTBOUND 'names/Level1' " +
          "nameEdges,nameToPersons " +
          "FILTER e.alien != true " +
          "RETURN {v:v}").toArray()