给定一个固定的 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"
}]
}]
}
Run Code Online (Sandbox Code Playgroud)
在另一个集合中引用“叶子”节点:
集合“人”
{
"name": {
"first": "John",
"last": "Doe"
},
"linkToLeaf": "<need to reference a leaf node. e.g. 'Level 1.2.1'>"
}
Run Code Online (Sandbox Code Playgroud)
并且需要查询数据:
使用 arangodb,对数据建模的最佳方法是什么?使用图表、简单的 JSON 文档、两者的混合,还是其他东西?
我正在开发一个新项目,我们希望跳转到 NoSQL,但来自传统 RDBMS 的背景,我会简单地使用递归连接对树进行建模,因此只需使用它的主键引用“叶节点”。
不知道该怎么做Arangodb...
有几点应该会影响您的数据模型:
在你的例子中,你展示了一些看起来非常自相似、像分形一样嵌套的东西。您当然可以将其弄平,并通过图形遍历嵌套执行您所做的操作。这对于客户端的代码来说是有益的,并且您不仅会受到固定数量的层的限制;而且还会受到限制。 图遍历会产生非常好的行为,您甚至可以迭代更深的动态。
新的 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})
Run Code Online (Sandbox Code Playgroud)
递归到结构:
db._query("FOR v IN 1..3 OUTBOUND 'names/Level1' nameEdges RETURN v"
).toArray()
Run Code Online (Sandbox Code Playgroud)
连接人员;我们显示顶点、边以及它们的路径:
db._query("FOR v, e, p IN 1..4 OUTBOUND 'names/Level1' " +
"nameEdges,nameToPersons " +
"RETURN {v:v, e:e, p:p}").toArray()
Run Code Online (Sandbox Code Playgroud)
您可以对边、顶点和路径的任意属性进行 Shure 过滤:
db._query("FOR v, e, p IN 1..4 OUTBOUND 'names/Level1' " +
"nameEdges,nameToPersons " +
"FILTER e.alien != true " +
"RETURN {v:v}").toArray()
Run Code Online (Sandbox Code Playgroud)