Neo4j
Графовая СУБД




Нелюбин Денис,
Тамтэк
Neo4j




        http://blog.beany.co.kr/archives/275
Граф




       upload.wikimedia.org
Граф




       graphviz.org
Граф
G := (V, E)
V — это непустое множество вершин, или узлов,
E — это множество пар вершин, называемых
рёбрами.
Neo4j Java API
GraphDatabaseService graphDb =
     new EmbeddedGraphDatabase(DB_PATH);
Node firstNode = graphDb.createNode();
firstNode.setProperty(
    "message", "Hello");

Relationship relationship =
    firstNode.createRelationshipTo(
    secondNode, RelTypes.KNOWS);
relationship.setProperty(
    "message", "brave Neo4j");
Neo4j REST API
POST {}
http://localhost:7474/db/data/node
PUT "Hello"
http://localhost:7474/db/data/node/1/properties/
message

POST {"to": "http://localhost:7474/db/data/node/2",
"type": "knows"}
http://localhost:7474/db/data/node/1/relationships
PUT "brave Neo4j"
http://localhost:7474/db/data/relationship/0/properties/
message
Neo4j REST API
GET http://localhost:7474/db/data/node/1
{
  "outgoing_relationships" : "http://localhost:7474/db/data/
node/1/relationships/out",
  "data" : {
    "message" : "Hello, "
  },
  "property" :
"http://localhost:7474/db/data/node/1/properties/{key}",
  "self" : "http://localhost:7474/db/data/node/1",
 "create_relationship" :
"http://localhost:7474/db/data/node/1/relationships"
}
Neo4j Web UI
Свойства узла
Neo4j Web UI
Свойства отношения
Neo4j Web UI
Визуализация
http://code.google.com/p/jo4neo/
     "ORM"             http://code.google.com/p/ogrm/


public class Message {
    transient Nodeid id;
    @neo(index=true) String message;
    @neo("KNOWS") Message knows;
}
ObjectGraph graph =
    ObjectGraphFactory.instance().
    get(graphDb);
Message hello = new Message();
hello.message = "Hello";
hello.knows = new Message();
graph.persist(hello);
TinkerPop Blueprints
     https://github.com/tinkerpop/blueprints/wiki
     "JDBC" для графовых баз (TinkerGraph, Neo4j,
     Sail(RDF), OrientDB, Dex, InfiniteGraph, Rexter).

Graph graph = new Neo4jGraph(DB_PATH);
Vertex node1 = graph.addVertex(null);
node1.setProperty(
    "message", "Hello");
Edge e = graph.addEdge(
    null, node1, node2, "knows");
e.setProperty(
    "message", "brave Neo4j");
Транзакции

Transaction tx = graphDb.beginTx();
try {
    // Mutating operations go here
    tx.success();
} finally {
    tx.finish();
}
Индексация и поиск

Index<Node> nodeIndex =
    graphDb.index().forNodes(NAME);

Node node = graphDb.createNode();
node.setProperty("message", "Hello");
nodeIndex.add(node, "message", "Hello");


Node foundNode = nodeIndex.get(
    "message", "Hello").getSingle();
Обход графа

Traverser traverser = node.traverse(
        Order.BREADTH_FIRST,
        StopEvaluator.END_OF_GRAPH,
        ReturnableEvaluator.
            ALL_BUT_START_NODE,
        RelTypes.KNOWS,
        Direction.OUTGOING);

for (Node relatedNode : traverser) {
        //TODO
}
Встроенные алгоритмы

• Нахождение путей между вершинами

• Нахождение кратчайших путей между
  вершинами

• Алгоритм Дейкстры (кратчайшее расстояние
  между вершинами во взвешенном графе)
Репликация




             docs.neo4j.org
Шардинг
Преимущества
• Нет схемы
• Гибкая и мощная графовая модель данных
• Мощные средства обработки графов



  Недостатки
• Нет схемы
• Нет распределенности
• Специфичная модель - подходит не для
  каждой предметной области
Когда использовать?
Если модель предметной области - множество
узлов с разнородными данными и большим
количеством разнородных связей между ними.

Иначе: SQL удобнее.


И если все данные умещаются на одной
физической машине.

Иначе: другой NoSQL удобнее.


И если вам подойдет лицензия...
Лицензия
http://neotechnology.com/products/price-list/

• Бесплатно: GPLv3 и AGPL (не LGPL!)
• $6000 (или $24000) в год: коммерческая
  лицензия




                                      stallman.org
Спасибо за внимание



    Нелюбин Денис,
    Тамтэк
    dnelubin@thumbtack.net

CodeFest 2012. Нелюбин Д. — Neo4j — графовая база данных

  • 1.
  • 2.
    Neo4j http://blog.beany.co.kr/archives/275
  • 3.
    Граф upload.wikimedia.org
  • 4.
    Граф graphviz.org
  • 5.
    Граф G := (V,E) V — это непустое множество вершин, или узлов, E — это множество пар вершин, называемых рёбрами.
  • 6.
    Neo4j Java API GraphDatabaseServicegraphDb = new EmbeddedGraphDatabase(DB_PATH); Node firstNode = graphDb.createNode(); firstNode.setProperty( "message", "Hello"); Relationship relationship = firstNode.createRelationshipTo( secondNode, RelTypes.KNOWS); relationship.setProperty( "message", "brave Neo4j");
  • 7.
    Neo4j REST API POST{} http://localhost:7474/db/data/node PUT "Hello" http://localhost:7474/db/data/node/1/properties/ message POST {"to": "http://localhost:7474/db/data/node/2", "type": "knows"} http://localhost:7474/db/data/node/1/relationships PUT "brave Neo4j" http://localhost:7474/db/data/relationship/0/properties/ message
  • 8.
    Neo4j REST API GEThttp://localhost:7474/db/data/node/1 { "outgoing_relationships" : "http://localhost:7474/db/data/ node/1/relationships/out", "data" : { "message" : "Hello, " }, "property" : "http://localhost:7474/db/data/node/1/properties/{key}", "self" : "http://localhost:7474/db/data/node/1", "create_relationship" : "http://localhost:7474/db/data/node/1/relationships" }
  • 9.
  • 10.
  • 11.
  • 12.
    http://code.google.com/p/jo4neo/ "ORM" http://code.google.com/p/ogrm/ public class Message { transient Nodeid id; @neo(index=true) String message; @neo("KNOWS") Message knows; } ObjectGraph graph = ObjectGraphFactory.instance(). get(graphDb); Message hello = new Message(); hello.message = "Hello"; hello.knows = new Message(); graph.persist(hello);
  • 13.
    TinkerPop Blueprints https://github.com/tinkerpop/blueprints/wiki "JDBC" для графовых баз (TinkerGraph, Neo4j, Sail(RDF), OrientDB, Dex, InfiniteGraph, Rexter). Graph graph = new Neo4jGraph(DB_PATH); Vertex node1 = graph.addVertex(null); node1.setProperty( "message", "Hello"); Edge e = graph.addEdge( null, node1, node2, "knows"); e.setProperty( "message", "brave Neo4j");
  • 14.
    Транзакции Transaction tx =graphDb.beginTx(); try { // Mutating operations go here tx.success(); } finally { tx.finish(); }
  • 15.
    Индексация и поиск Index<Node>nodeIndex = graphDb.index().forNodes(NAME); Node node = graphDb.createNode(); node.setProperty("message", "Hello"); nodeIndex.add(node, "message", "Hello"); Node foundNode = nodeIndex.get( "message", "Hello").getSingle();
  • 16.
    Обход графа Traverser traverser= node.traverse( Order.BREADTH_FIRST, StopEvaluator.END_OF_GRAPH, ReturnableEvaluator. ALL_BUT_START_NODE, RelTypes.KNOWS, Direction.OUTGOING); for (Node relatedNode : traverser) { //TODO }
  • 17.
    Встроенные алгоритмы • Нахождениепутей между вершинами • Нахождение кратчайших путей между вершинами • Алгоритм Дейкстры (кратчайшее расстояние между вершинами во взвешенном графе)
  • 18.
    Репликация docs.neo4j.org
  • 19.
  • 20.
    Преимущества • Нет схемы •Гибкая и мощная графовая модель данных • Мощные средства обработки графов Недостатки • Нет схемы • Нет распределенности • Специфичная модель - подходит не для каждой предметной области
  • 21.
    Когда использовать? Если модельпредметной области - множество узлов с разнородными данными и большим количеством разнородных связей между ними. Иначе: SQL удобнее. И если все данные умещаются на одной физической машине. Иначе: другой NoSQL удобнее. И если вам подойдет лицензия...
  • 22.
    Лицензия http://neotechnology.com/products/price-list/ • Бесплатно: GPLv3и AGPL (не LGPL!) • $6000 (или $24000) в год: коммерческая лицензия stallman.org
  • 23.
    Спасибо за внимание Нелюбин Денис, Тамтэк dnelubin@thumbtack.net

Editor's Notes

  • #3 CAP теорема. C - Consistency - целостность данных. A - Availability - доступность данных. P - Partition Tolerance - возможность распределить данные между разными машинами в сети - единственный возможный способ хранить действительно большие объемы данных. Теорема - возможно реализовать лишь две &amp;quot;буквы&amp;quot; из CAP. Neo4j - на грани CA. Целостность достигается за счет полноценных транзакций. Доступность достигается за счет репликации - каждый клиент работает со своей копией данных (embed база).
  • #4 Это не тот граф :)
  • #5 Граф выглядит как-то так.
  • #6 Математический граф - множество вершин и ребер между ними. Узлы и отношения. В Neo4j все отношения имеют явно заданный тип. В Neo4j все узлы и отношения могут иметь свойства - пары ключ-значение.
  • #7 Обычное Java API. Явно создаются узлы и отношения между ними. Тип отношения - enum. База - embedded. Свойства - ключ-значение. Для отношений явно задается начальный и конечный узлы (подразумевается направленность связей). Буква &amp;quot;J&amp;quot; в названии говорит нам, что СУБД написана на Java.
  • #8 Весьма продвинутое REST API. Входит в состав дистрибутива БД (на базе HTTP сервера Jetty). POST на /node создает новый узел. PUT на properties/&lt;name&gt; создает/обновляет свойство. POST на /relationships создает отношение. Права доступа никак не ограничены. Нет авторизации и аутентификации. Любой, кто получит доступ к REST может делать что угодно.
  • #9 Сведения об узле выглядят так (сокращенно). Указаны URL для всех операций.
  • #10 Красивая веб мордочка. Авторизации и аутентификации тоже нет. Хороший инструмент администратора.
  • #12 Очень мощные настройки стилей. Можно отображать/расскрашивать узлы по-разному в зависимости от значения их свойств. Есть и плагин к Eclipse.
  • #13 Существуют аналоги ORM  (скорее OGM - Object Graph Mapping). Класс - узел. Свойство класса - свойство узла. Ссылки на другие объекты - отношения. Nodeid - служебная информация. Недостаток - графовая модель данных искуственно ограничивается. Сложно передать множество связей. Возникают проблемы при рефакторинге, т.к. полные имена классов хранятся в &amp;quot;скрытых&amp;quot; свойствах узлов. Теряется гибкость графовой модели.
  • #14 &amp;quot;Аналог&amp;quot; JDBC для графовых БД. Графовых БД уже довольно много. Интересен Sail - Storage And Inference Layer для RDF. RDF (Resource Description Framework) - мощнейщий механизм описания данных (метаданных). Триплеты: субъект-предикат-объект. Основа семантического веба 5.0 Зашли в дебри графовых БД... Вернемся обратно к Neo4j.
  • #15 Транзакции - есть. Выглядят и работают точно так же как в обычных SQL базах.
  • #16 Индексы - отдельные сущности базы. Создаются явно (однако существует и &amp;quot;автоиндекс&amp;quot;). Индексироваться могут любые свойства узлов (и связей). Возможны полнотекстовые индексы. Результат поиска по индексу - id узлов. Движок - Apache Lucene.
  • #17 Имеется мощный API для обхода графа. В данном случае: - начиная с данного узла и до конца графа - в ширину (сначала непосредственные потомки, затем &amp;quot;внуки&amp;quot; и т.д.) - включать все узлы, кроме начального - идти по связям типа KNOWS - в направлении ОТ текущего узла Обход графа - &amp;quot;ленивый&amp;quot;. Не строится список узлов, а вычисляется следующий узел в итераторе.
  • #18 Взвешенный граф - связи между вершинами имеют вес (стоимость). В данном случае вес может определяться любым свойством связи.
  • #19 Картинка из официальной документации. Классическая репликация. Каждый узел имеет полную копию всех данных. Apache ZooKeeper следит за доступностью серверов и управляет работой Load Balancerа.
  • #20 Пустой слайд. Нет поддержки шардинга со стороны БД.
  • #22 Типичное применение: социальные сети и графы &amp;quot;друзей&amp;quot;.
  • #23 Полнофункциональные версии доступны только под &amp;quot;вирусными&amp;quot; GPL лицензиями. Их можно использовать ТОЛЬКО в GPL коде (Столлман торжествует!). Для проприетарных разработок - коммерческая лицензия.