ArangoDB-основы создания графов


Я абсолютно новый в ArangoDB. Я знаком с Neo4J, но был привлечен к производительности ArangoDB и многомодельному дизайну. Документация кажется очень глубокой, но у меня возникли проблемы с началом работы.

Я хотел бы знать простой способ выполнения некоторых базовых графовых операций. Все, что я нашел до сих пор, говорит мне, как соединить целые коллекции вместе, но я хотел бы просто иметь возможность определить узел, определить другой узел и определить границу между ними.

В идеале через HTTP, как я могу:

  • добавьте узел к графу
  • создайте ребро между двумя узлами, которые я добавил в свой граф
  • создайте коллекцию и добавьте в нее существующие узлы

В качестве примера я хотел бы создать простой граф, подобный дереву, показанному здесь: https://www.arangodb.com/2015/07/data-modeling-with-multi-model-databases/

Дерево примеров обслуживания парка воздушных судов

Я хотел бы получить основные инструкции о том, как создать подмножество этого диаграмма. Я хотел бы:

  • создайте узлы с именами airline0 и airline1 в коллекции с именем fleets.
  • создание узлов plane0, plane1, plane2 в коллекции под названием planes. - Поместите произвольный атрибут в документ каждой плоскости-скажем, цвет.
  • создайте узел под названием Jennifer в коллекции под названием pilots.

Далее я хотел бы соединить график. Судя по документации, ребра сами по себе являются документами и, следовательно, могут иметь атрибуты. Я бы например, создать следующие ребра:

  • (airline0)-[owns]->(plane0)
  • (airline0)-[owns]->(plane1) это ребро имеет since: 2013 в качестве атрибута
  • (airline1)-[owns]->(plane2)
  • (airline1)-[previouslyOwned]->(plane1) between: [1999,2013]
  • (plane0)-[inFleet]->(airline0)
  • (plane1)-[inFleet]->(airline0)
  • (plane1)-[wasInFleet]->(airline1) between: [1999,2013]
  • (plane2)-[inFleet]->(airline1)
  • (jennifer)-[canfly]->(plane0)
  • (plane0)-[hasPilot]->(jennifer)

Пожалуйста, покажите мне, как я могу создать такой граф через HTTP. Если не HTTP, то я хотел бы знать, как это сделать через arangosh.

1 3

1 ответ:

Позвольте мне начать с арангоша, потому что его легче читать. Я дам команды HTTP в качестве дополнения.

Arangodb Shell

Вам понадобятся три коллекции документов "флоты", "самолеты" и "пилоты" , как вы упомянули выше, и по крайней мере одно ребро коллекция для хранения структуры графика. Если вы хотите пересечь структуру графа, прыгая между "владеет" и "inFleet" и "canfly", я предлагаю использовать одну коллекцию "отношений" и дать ребрам тип атрибута".

Альтернативным решением является использование трех пограничных коллекций "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)]
Далее создайте документы в сборнике "флоты". Я буду использовать название авиакомпании в качестве ключа. В зависимости от вашего варианта использования, может быть лучший ключ. Например, может быть, существует универсальная аббревиатура (например, 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 аналогичен описанному выше созданию документа. Кроме того, вам нужно предоставить ключи "от" и "до" вершин, которые вы хотите соединять.

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' });
...

Теперь, чтобы следовать по пути "Дженнифер может летать на planeX, принадлежащем airlineY", используйте:

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"
    }
  }
]

Или повернуть путь вспять (без использования "инфлит" и "хаспилот"):

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

Позвольте мне привести вам пример для различных типов команд, выполненных выше.
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