
Колись, приблизно у 2005 році, я захопився ідеєю створення бази знань, яка не мала б чіткої табличної структури й працювала б за принципом іменованих вузлів і зв’язків між ними. Основна ідея полягала в тому, що сам вузол не містив би жодної інформації, а всю інформацію задавали б його оточення та зв’язки. Тоді я написав невеликий код сховища цих вузлів і зв’язків, а також найпростіших операцій над ними. Але зовсім не зберігати інформацію у вузлах було надто складно, тож я прив’язував до кожного вузла одну текстову властивість (у Neo4j у вузол можна записати багато властивостей різних типів, а потім звертатися до них за назвою).
Цей рушій спочатку було написано на C#, потім кілька разів переписано, але поступово я втратив до нього інтерес. Згадав свою розробку, коли нещодавно натрапив на Neo4j. Упізнавши деякі власні ідеї, захотів докладніше з нею познайомитися.
Neo4j я встановив на віртуальну машину. Виявилося, що вбудований фронтенд має вебінтерфейс і доступний за адресою http://localhost:7474.
Після переходу за цією адресою мені запропонували ввести ім’я користувача й пароль. При цьому була підказка, що типове ім’я користувача — “node4j”, а пароль такий самий. Далі на мене чекала сторінка привітання з трьома основними кнопками: Start Learning, Write Code і Monitor:

Насамперед я перейшов на сторінку моніторингу. Одразу над блоком із кнопками додався ще один блок, у якому я побачив статистику БД (на знімку екрана я вже встиг додати один вузол):

Виявилося, що нова інформація додається на екран такими блоками, які можна видаляти, закріплювати та гортати, а найстаріші з них переміщуються вниз.
У самому верху був командний рядок для виконання місцевої мови запитів — за аналогією із SQL, тільки тут вона називається Cypher Query Language. Мені одразу захотілося додати до бази хоч щось, але не таке складне, як пропонував вбудований приклад “play movie graph”: там була ціла сторінка команд, яка, вочевидь, створювала багато сутностей із властивостями та зв’язками між ними. Натомість я перейшов за посиланням на опис команди CREATE і за прикладом виконав CREATE (n), створивши найпростіший окремий вузол.
Далі я все-таки вирішив знайти, де задано порти, на яких сервер очікує з’єднання, щоб підключатися до віртуальної машини зі свого браузера, а не з її локального браузера. Виявилося, що потрібно розкоментувати рядок
#org.neo4j.server.webserver.address=0.0.0.0
у файлі conf/neo4j-server.properties
Далі спробував створити кілька вузлів:
CREATE (a:Country {name:'Украина'}),(b:Country {name:'Россия'}),(c:Country {name:'Беларусь'}),(d:Country {name:'Казахстан'})
я отримав:
Added 3 labels, created 4 nodes, set 4 properties, statement executed in 664 ms.
Коли ж я захотів пов’язати країни відношенням ‘Border’, тобто вказати, яка з якою межує, виявилося, що в Neo4j відношення може бути лише односпрямованим. Проте з бази можна робити вибірки, ігноруючи напрямок. Довелося змиритися із цим і встановити зв’язки довільного напрямку:
MATCH (a:Country {name:'Украина'}),(b:Country {name:'Россия'}),(c:Country {name:'Казахстан'}),(d:Country {name:'Беларусь'}) CREATE (a)-[r:Border]->(b),(a)-[t:Border]->(d),(b)-[y:Border]->(c),(d)-[u:Border]->(b)
Тут спочатку у змінні a,b,c,d вибираються всі потрібні країни, а потім між ними встановлюються зв’язки з міткою (Label) “Border”. Помилуватися результатом можна, вибравши всі зв’язки “Border”:
MATCH ()-[r:Border]-() RETURN r
або всі країни
MATCH (a:Country) RETURN a
Після того як я, вправляючись, додав ще кілька країн і зв’язків між ними, уже можна було отримати таке зображення:

Варто сказати, що на графі зв’язки хоча й притягують пов’язані вузли, але ті часто розміщуються не найкращим чином. Якщо посувати їх вручну, можна отримати вдаліше розташування, ніж початкове.
Мені здалося, що вбудований візуалізатор має бути не єдиним. Трохи пошукавши, я знайшов ще кілька прикладів візуалізації:
http://neo4j.com/developer/guide-data-visualization/#_presentation_svg_based_graph_interaction
Що цікаво, зв’язки також можуть мати властивості, як і вузли. Але мені здалося не дуже зрозумілим обмеження кількості типів зв’язків: за одним джерелом — 32768, за іншим — 65536. У моїй БД типи зв’язків задавалися самими вузлами, що дозволяло за потреби будувати ієрархії типів зв’язків, а також мати значно більше їхніх різновидів.
Оболонка моєї БД виглядала приблизно так:

Там було загальне дерево сутностей, а також окремі форми для роботи з деякими типами сутностей, зокрема персоналіями (по суті, телефонний довідник) і каталогом дисків. Усе можна було переглянути як список або дерево. Передбачалося, що зрештою я вироблю зручну форму зберігання знань, які легко переплітаються між собою й не мають чіткої однорідної структури. Зараз, звісно, я не думаю, що обов’язково було розробляти БД із нуля: цілком можна було взяти за основу Firebird або MySQL і реалізувати механізм зберігання та вибірки вузлів і зв’язків між ними у вигляді таблиць. Зараз в одному зі своїх експериментів я саме так і роблю.

Большое спасибо за полезную и интересную страничку!
Занимаюсь сходными вещами.
Было интересно познакомиться с Вашим подходом.
Спасибо!