ArangoDB - 图形创建基础知识

5
我是一个全新的ArangoDB用户。我熟悉Neo4J,但被ArangoDB的性能和多模型设计所吸引。文档似乎非常深入,但我在开始方面遇到了一些困难。
我想知道如何进行一些基本的图形操作。到目前为止,我发现的所有内容都告诉我如何将整个集合连接在一起,但我只想简单地定义一个节点、定义另一个节点,并定义它们之间的边。
理想情况下通过HTTP,我该如何:
  • 向图中添加一个节点
  • 创建两个我已经添加到我的图形中的节点之间的边
  • 创建一个集合并将现有节点添加到该集合中
例如,我想创建一个简单的图形,就像这里所示的树形结构:https://www.arangodb.com/2015/07/data-modeling-with-multi-model-databases/

Aircraft fleet maintenance example tree

我想获得有关如何创建此图形子集的基本说明。我想要:
  • 在名为fleets的集合中创建名为airline0airline1的节点。
  • 在名为planes的集合中创建节点plane0plane1plane2。- 在每个飞机的文档中放置一个任意属性-比如说颜色。
  • 在名为pilots的集合中创建名为Jennifer的节点。
接下来,我想连接图形。根据文档,边本身是文档,因此可以具有属性。我想创建以下边:
  • (airline0)-[拥有]->(plane0)
  • (airline0)-[拥有]->(plane1) 这条边具有since: 2013属性
  • (airline1)-[拥有]->(plane2)
  • (airline1)-[之前拥有]->(plane1) between: [1999,2013]
  • (plane0)-[在机队中]->(airline0)
  • (plane1)-[在机队中]->(airline0)
  • (plane1)-[曾在机队中]->(airline1) between: [1999,2013]
  • (plane2)-[在机队中]->(airline1)
  • (jennifer)-[能驾驶]->(plane0)
  • (plane0)-[有飞行员]->(jennifer)

请向我展示如何通过HTTP创建这样的图。如果不是HTTP,请告诉我如何通过arangosh完成此操作。

1个回答

10

让我们从arangosh开始,因为它更容易阅读。我将把HTTP命令作为补充说明。

ArangoDB Shell

如您所提到的,您需要三个文档集合“fleets”、“planes”和“pilots”,以及至少一个边缘集合来保存图形结构。如果您想在“拥有”、“inFleet”和“canfly”之间跳转遍历图形结构,则建议使用一个名为“relations”的集合,并给边缘分配一个属性“type”。

另一种解决方案是使用三个边缘集合“owns”、“inFleet”和“canfly”。为了提供更基于事实的推荐,了解更多关于您的用例将会很有帮助。

arangosh [_system]> db._create("fleets");
[ArangoCollection 139792431, "fleets" (type document, status loaded)]

arangosh [_system]> db._create("planes");
[ArangoCollection 140382255, "planes" (type document, status loaded)]

arangosh [_system]> db._create("pilots");
[ArangoCollection 140972079, "pilots" (type document, status loaded)]

arangosh [_system]> db._createEdgeCollection("relations");
[ArangoCollection 141103151, "relations" (type edge, status loaded)]

接下来,在“fleets”集合中创建文档。我将使用航空公司名称作为键。根据您的用例,可能有更好的键。例如,可能存在通用缩写(如Lufthansa的LH)。

arangosh [_system]> db.fleets.save({ _key: "airline0", name: "Airline 0" });
arangosh [_system]> db.fleets.save({ _key: "airline1", name: "Airline 1" });

同样的方法也适用于飞机和飞行员:

arangosh [_system]> db.planes.save({ _key: "plane0", name: "Plane Zero", color: "red" })
arangosh [_system]> db.planes.save({ _key: "plane1", name: "Plane One", color: "red" })
arangosh [_system]> db.planes.save({ _key: "plane2", name: "Plane One", color: "green" })
arangosh [_system]> db.pilots.save({ _key: "jennifer", name: "Jenifer" });

根据您的使用情况选择键。如果没有“自然”键,则省略“_key”属性。ArangoDB将为您生成唯一的键。

接下来,添加上面创建的节点之间的关系。在ArangoDB 2.8中的语法类似于上面创建文档时的语法。此外,您需要提供要连接的顶点的“from”和“to”键。

arangosh [_system]> db.relations.save("fleets/airline0", "planes/plane0", { type: 'owns' });
arangosh [_system]> db.relations.save("fleets/airline0", "planes/plane1", { type: 'owns', since: 2013 });
arangosh [_system]> db.relations.save("fleets/airline1", "planes/plane2", { type: 'owns' });
arangosh [_system]> db.relations.save("fleets/airline1", "planes/plane1", { type: 'previouslyOwned', begin: 1999, end: 2013 });
arangosh [_system]> db.relations.save("pilots/jennifer", "planes/plane0", { type: 'canfly' });

如果'inFleet'/'wasInFleet'/'hasPilot'和'owns'/'previouslyOwned'/'canfly'相反,则不需要为它创建单独的边,因为边是有方向性的。
如果'owns'和'inFleet'之间存在差异,您可以按照上述方式创建关系:
arangosh [_system]> db.relations.save("planes/plane0", "fleets/airline0", { type: 'inFleet' });
...

现在,为了跟随“Jennifer可以驾驶属于AirlineY的PlaneX”的路径,请使用以下命令:
arangosh> db._query("FOR v, e IN OUTBOUND 'pilots/jennifer' relations FILTER e.type == 'canfly' FOR w, f IN INBOUND v relations FILTER f.type == 'owns' RETURN { plane: v, airline: w }")
[
  {
    "plane" : {
      "color" : "red",
      "name" : "Plane Zero",
      "_id" : "planes/plane0",
      "_rev" : "153686063",
      "_key" : "plane0"
    },
    "airline" : {
      "name" : "Airline 0",
      "_id" : "fleets/airline0",
      "_rev" : "149884975",
      "_key" : "airline0"
    }
  }
]

或者反转路径(不使用'inFleet'和'hasPilot'):

arangosh> db._query("FOR v, e IN OUTBOUND 'fleets/airline0' relations FILTER e.type == 'owns' FOR w, f IN INBOUND v relations FILTER f.type == 'canfly' RETURN { plane: v, w: w }")
[
  {
    "plane" : {
      "color" : "red",
      "name" : "Plane Zero",
      "_id" : "planes/plane0",
      "_rev" : "153686063",
      "_key" : "plane0"
    },
    "w" : {
      "_id" : "pilots/jennifer",
      "_rev" : "330240047",
      "_key" : "jennifer"
    }
  }
]

HTTP

HTTP是一种用于传输超文本的协议。它允许客户端和服务器之间进行通信,使得网页能够展示在我们的浏览器上。

下面我将为您举例不同类型的命令。

arangosh [_system]> db._create("fleets");

这是翻译成中文的结果

curl -X POST --data-binary @- --dump - http://localhost:8529/_api/collection <<EOF
{ 
  "name" : "fleets" 
}
EOF

下一个
arangosh [_system]> db._createEdgeCollection("relations");

翻译成

curl -X POST --data-binary @- --dump - http://localhost:8529/_api/collection <<EOF
{ 
  "name" : "relations", "type": 3 
}
EOF

下一步。
arangosh [_system]> db.fleets.save({ _key: "airline0", name: "Airline 0" });

翻译成

curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products <<EOF
{ "_key": "airline0", "name": "Airline 0" }
EOF

下一步。
db.relations.save("pilots/jennifer", "planes/plane0", { type: 'canfly' });

翻译成

curl -X POST --data-binary @- --dump - http://localhost:8529/_api/edge/?collection=relations&from=pilots/jennifer&to=planes/plane0 <<EOF
{ 
  "type" : "canfly" 
}
EOF

1
太好了!谢谢!在更深入地查看文档后,我找到了一些内容,但直到现在遍历方式才变得清晰明了。我很想了解拥有单个边缘集合与多个边缘集合的优势。我能够跨越多个边缘集合进行遍历吗?还是只能在一个集合内进行遍历? - Nate Gardner
1
另一个问题:graph._addVertexCollectiondb._create之间的区别是什么? - Nate Gardner
1
ArangoDB支持命名和未命名图形。 命名图形是使用“graph....”创建的。 您还可以使用使用“db....”创建的边缘集合的匿名图形。 是的,您可以使用多个边缘集合进行遍历。 由于评论大小受限,因此在https://groups.google.com/forum/#!forum/arangodb上继续讨论可能更容易。 - fceller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接