goodbyegangsterのブログ

備忘録的な

Neo4jの基本的操作方法の確認

Neo4jをインストールして、基本的な操作方法を確認します。

環境

  • Ubuntu 20.04.2 LTS
  • Neo4j Community Edition 4.3.2
  • openjdk 11.0.11

Neo4jのインストール

openjdkのインストール

Neo4jはjavaらしいので、Neo4j ver4.xの動作環境であるopenjdk 11をインストールします。openjdk公式のppa(Personal Package Archives)を追加してjavaをインストールしています。

Linux Installation - Debian

$ sudo add-apt-repository -y ppa:openjdk-r/ppa
$ sudo apt-get update

$ sudo apt install openjdk-11-jre-headless
$ java --version
openjdk 11.0.11 2021-04-20
OpenJDK Runtime Environment (build 11.0.11+9-Ubuntu-0ubuntu2.20.04)
OpenJDK 64-Bit Server VM (build 11.0.11+9-Ubuntu-0ubuntu2.20.04, mixed mode, sharing)

Neo4jのインストール

Neo4jのリポジトリを追加して、stable環境のNeo4jをインストールします。

$ sudo wget -O - https://debian.neo4j.com/neotechnology.gpg.key | sudo apt-key add -
$ sudo echo 'deb https://debian.neo4j.com stable 4.3' | sudo tee -a /etc/apt/sources.list.d/neo4j.list
$ sudo apt-get update

$ sudo apt-get install neo4j
$ neo4j version
neo4j 4.3.2

Neo4jのコンフィグファイルの編集

コンフィグを編集して、リモートからも接続可能とします。

Configuration - Ports

/etc/neo4j/neo4j.conf

...
#*****************************************************************
# Network connector configuration
#*****************************************************************

# With default configuration Neo4j only accepts local connections.
# To accept non-local connections, uncomment this line:
dbms.default_listen_address=0.0.0.0
...

Neo4jユーザーの初期化

Neo4jユーザーの初期パスワードを設定します。

Set an initial password

$ sudo neo4j-admin set-initial-password password
Selecting JVM - Version:11.0.11, Name:OpenJDK 64-Bit Server VM, Vendor:Ubuntu
Changed password for user 'neo4j'.

Neo4jの起動

Systemdの自動設定をして、Neo4jのサービスを起動します。

$ sudo systemctl enable neo4j
$ sudo systemctl start neo4j

Neo4j Browserにアクセスしてみます。

Neo4j Browser is a tool for developers to interact with the graph. It is the default interface for both Enterprise and Community Editions of the Neo4j database.

Neo4j Browser

ローカルのブラウザから、http://(Server IP Address):7474/browser/のURLにアクセスし、上記で設定したユーザー・パスワード情報を入力します。

f:id:goodbyegangster:20210712003347p:plain

ログインできました。

f:id:goodbyegangster:20210712003357p:plain

Graph database concepts

Neo4jのグラフDBを構成する要素を、以下の資料より確認します。

Graph database concepts

Node

Nodes are often used to represent entities. The simplest possible graph is a single node.

グラフDBを構成する最小要素、ぐらいの理解です。

Label

Labels are used to shape the domain by grouping nodes into sets where all nodes that have a certain label belongs to the same set.
For example, all nodes representing users could be labeled with the label :User. With that in place, you can ask Neo4j to perform operations only on your user nodes, such as finding all users with a given name.

複数のNodeをグループ化してくれるもの、ぐらいの理解です。

Relationship

A relationship connects two nodes. Relationships organize nodes into structures, allowing a graph to resemble a list, a tree, a map, or a compound entity — any of which may be combined into yet more complex, richly inter-connected structures.

NodeとNodeを結ぶ矢印のこと、と理解しています。

Relationship types

A relationship must have exactly one relationship type.

Relationshipをグループ化するために付与する名前、みたいなものと理解しています。

Propertie

Properties are name-value pairs that are used to add qualities to nodes and relationships.

NodeとRelationshipに付与できるKey-Pair、まさに属性、と理解しています。

Cypher

Neo4jでは、Cypherというクエリ言語を利用してデータを操作します。

Cypher is a declarative graph query language that allows for expressive and efficient querying, updating and administering of the graph. It is designed to be suitable for both developers and operations professionals. Cypher is designed to be simple, yet powerful; highly complicated database queries can be easily expressed, enabling you to focus on your domain, instead of getting lost in database access.

What is Cypher?

Nodeの表現

Example: Nodes in Cypher

()                  //anonymous node (no label or variable) can refer to any node in the database  
(p:Person)          //using variable p and label Person  
(:Technology)       //no variable, label Technology  
(work:Company)      //using variable work and label Company  

(variable:lable)と記述します。

Relationshipの表現

Representing Relationships in Cypher

//data stored with this direction
CREATE (p:Person)-[:LIKES]->(t:Technology)

//query relationship backwards will not return results
MATCH (p:Person)<-[:LIKES]-(t:Technology)

//better to query with undirected relationship unless sure of direction
MATCH (p:Person)-[:LIKES]-(t:Technology)

上記例ではLIKESがRelationship Typeとなり、Nodeと同じように[variable:relationship type]と書くことで、Relationshipにもvariableを指定できます。

Propertiesの表現

Node or Relationship Properties

(p:Person {name: 'Jennifer'})                //Node property

-[rel:IS_FRIENDS_WITH {since: 2018}]->       //Relationship property

Nodeを表現する丸括弧やRelationshipを表現する角括弧の中で波括弧を記載して、Propatiesとしたいkey-pairの情報を書いてあげます。

データの操作

標準で作成されているneo4jデータベースにデータに対して、実際にCypherクエリを実行してみます。

$ SHOW DATABASES
╒════════╤════════════════╤════════════╤═════════════════╤═══════════════╤═══════╤═════════╤══════╕
│"name""address""role""requestedStatus""currentStatus""error""default""home"│
╞════════╪════════════════╪════════════╪═════════════════╪═══════════════╪═══════╪═════════╪══════╡
│"neo4j""localhost:7687""standalone""online""online"""truetrue  │
├────────┼────────────────┼────────────┼─────────────────┼───────────────┼───────┼─────────┼──────┤
│"system""localhost:7687""standalone""online""online"""falsefalse │
└────────┴────────────────┴────────────┴─────────────────┴───────────────┴───────┴─────────┴──────┘

2. Show the status of all databases

登録するデータ

以下のような構成のデータを作成します。

f:id:goodbyegangster:20210712003414p:plain

Nodeの登録

Personラベルを持つ3つのNodeSakura Miko,Usada Pekora,Houshou Marineを作成します。

CREATE
  (a:Person {name:'Sakura Miko', age: 18}),
  (b:Person {name:'Usada Pekora', age: 111}),
  (c:Person {name:'Houshou Marine', age: 17})
RETURN a.name, b.name, c.name;

Hololiveラベルを持つ2つのNodeHololive 0th gen,Hololive 3rd genを作成します。

CREATE
  (a:Hololive {name:'Hololive 0th gen'}),
  (b:Hololive {name:'Hololive 3rd gen'})
RETURN a.name, b.name;

Create nodes

Relationshipの登録

NodeSakura MikoとNodeHololive 0th genとを、belong_toというタイプでRelationshipを結びます。

MATCH
  (a:Person),
  (b:Hololive)
WHERE a.name = 'Sakura Miko' AND b.name = 'Hololive 0th gen'
CREATE (a)-[r:belong_to]->(b)
RETURN type(r);

Personラベルを持ち、nameのPropertyがSakura MikoでないNodeを、Hololive 3rd genというNodeと、belong_toというタイプでRelationshipを結びます。

MATCH
  (a:Person),
  (b:Hololive)
WHERE a.name <> 'Sakura Miko' AND b.name = 'Hololive 3rd gen'
CREATE (a)-[r:belong_to]->(b)
RETURN a.name, type(r), b.name;

NodeSakura MikoとNodeHoushou MarineからNodeUsada Pekoraに対して、loveというタイプでPropatyを付与してRelationshipを結びます。

MATCH
  (mikochi:Person {name:'Sakura Miko'}),
  (pekora:Person {name:'Usada Pekora'}),
  (sencho:Person {name:'Houshou Marine'})
CREATE (mikochi)-[:love {depth: 10}]->(pekora)<-[:love {depth: 5}]-(sencho);

Create relationships

検索

NodeHololive 3rd genbelong_toのRelationshipをもつPersonラベルのNodeを検索。

MATCH (p:Person)-[r:belong_to]->(h:Hololive)
WHERE h.name = 'Hololive 3rd gen'
RETURN p, r, h

f:id:goodbyegangster:20210712003427p:plain

NodeUsada Pekoraに対してloveのRelationshipを持ち、Relationshipのdepthの値が最も大きいラベルPersonのNodeを検索。

MATCH (n:Person)-[r:love]->(pekora:Person {name:'Usada Pekora'})
WITH max(r.depth) as maximum
MATCH (n)-[r]->(pekora)
WHERE r.depth = maximum
RETURN n, r, pekora

f:id:goodbyegangster:20210712003437p:plain

更新

NodeSakura Miko{nickname: 'Mikochi'}というPropatyを追加。

MATCH (p:Person {name:"Sakura Miko"})
SET p.nickname = 'Mikochi'

Updating Data with Cypher

削除

NodeHoushou Marineを削除。

MATCH (n:Person)
WHERE n.name = 'Houshou Marine'
DETACH DELETE n

Delete a Node and Relationship

Reference

The Neo4j Cypher Manual v4.3

cypher-refcard