LoginSignup
2
2

More than 3 years have passed since last update.

GraphDB Neo4j on Docker

Last updated at Posted at 2019-05-20
  • Neo4jを使ってみたのでその時のことをメモしておく

下記のステップで進めます

  1. Dockerコンテナの準備
  2. Dockerコンテナの起動
  3. Neo4j管理画面入室
  4. Cyperを利用したデータの操作

1. Dockerコンテナの準備

$ mkdir graphdb-neo4j
$ cd graphdb-neo4j
$ docker pull neo4j

2. Dockerコンテナの起動

docker コマンドで起動

$ docker run \
    --detach \
    --publish=7474:7474 --publish=7687:7687 \
    --volume=$HOME/neo4j/data:/data \
    --volume=$HOME/neo4j/logs:/logs \
    --volume=$HOME/neo4j/conf:/conf \
    --ulimit=nofile=40000:40000 \
    neo4j:latest
# 確認
$ docker CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                                      NAMES
905109eecfc6        neo4j:latest        "/sbin/tini -g -- /d…"   12 seconds ago      Up 11 seconds       0.0.0.0:7474->7474/tcp, 7473/tcp, 0.0.0.0:7687->7687/tcp   affectionate_elgamal

# コンテナに入る
$ docker exec -it neo4j bin/cypher-shell
username:****
password:****

# 退出
$ :exit

docker-compose.ymlの場合

docker-compose.yml
version: '2'

services:
  neo4j:
    image: neo4j:latest
    ports:
      - "7474:7474"
      - "7687:7687"
    volumes:
      - ${HOME}/neo4j/data:/data
      - ${HOME}/neo4j/logs:/logs
      - ${HOME}/neo4j/conf:/conf
    ulimits:
      nofile:
        soft: 40000
        hard: 40000

docker-compose.ymlで起動

$ docker-compsoe up -d
$ docker-compose            Name                         Command               State                            Ports                          
------------------------------------------------------------------------------------------------------------------------------
neo4j_neo4j_1_12ca70742005   /sbin/tini -g -- /docker-e ...   Up      7473/tcp, 0.0.0.0:7474->7474/tcp, 0.0.0.0:7687->7687/tcp

# コンテナに入る
$ docker-compose exec neo4j bin/cypher-shell
username:****
password:****

# 退出
$ :exit

3. Neo4j管理画面入室

  • 起動が確認できたらブラウザからNeo4jの管理画面に入室します
  • 192.168.33.10:7474
  • ホストアドレスは自分の環境に合わせて変更
  • 初回はusernameとpasswordの初期設定を求められるもよう

4. Cyperを利用したデータの操作

公式ドキュメント

  • 公式ドキュメントを参考に軽くテストしてく
ノード作成
  • ノードとはデータ点のこと

基本構文
CREATE (ParameterName:Label { field1: value1, field2: value2 })

一意制約
MATCH (ParameterName:Label { field1: value1, field2: value2 }) CREATE UNIQUE (ParameterName)

複数のラベルを指定
CREATE (ParameterName:Label1:Label2 { field1: value1, field2: value2 })

複数ノード作成*
CREATE (node1),(node2),...

結果を取得
CREATE (node1) RETURN paramName.field1

ノードと一緒にリレーションも作成
CREATE (node1:Label{field1:value})-[:relationName]->(node2:label{field1:value})

# ノードを2件作成
$ CREATE (n1:Person:Japanese { name: 'Sato', blood: 'A', age:25}),(n2:Person:Korea {name:'Kim', blood:'O', age:23})

# ノード3件とリレーションも作成
$ CREATE (n1:Person:Japanese { name: 'Endo', blood: 'AB', age:20}),(n2:Person:Japanese {name:'Aoki', blood:'A', age:18}),(n3:Person:Japanese {name:'Takagi', blood:'B', age:30}),(n1)-[:friends]->(n2)-[:friends]->(n3)-[:friends]->(n1)-[:friends]->(n3)
リレーションを追加
  • リレーションとはエッジ(辺)のこと

基本構文
CREATE (node1)-[:Relations]->(node2)

相互リレーション
CREATE (node1)-[:Relations]->(node2)-[:relation]->(node1)

# SatoさんとKimさんは友達同士という関係を追加
$ MATCH (n1:Person { name: 'Sato'}),(n2:Person {name:'Kim'}) CREATE (n1)-[:friends]->(n2)-[:friends]->(n1)

# SatoさんはAokiさんと友達という関係を追加
$ MATCH (n1 {name:'Sato'}),(n2 {name:'Aoki'}) CREATE (n1)-[:friends]->(n2) 

データを取得

基本構文
MATCH (n) RETURN n

# 全件取得
$ MATCH (n) RETURN n

ラベル検索
MATCH (n:LabelName) RETURN n

# 日本人というラベルで検索
$ MATCH (n:Japanese) RETURN n

属性検索 ※属性検索ではラベルは必須ではありません
MATCH (n:LabelName { name:'value' }) RETURN n

# Kimさんを検索
$ MATCH (n:Person {name:'Kim'}) RETURN n

WHERE句を使った検索
MATCH (n) WHERE n.field=value RETURN n

# Kimさんを検索
$ MATCH (n) WHERE n.name='Kim' RETURN n

前方一致
UNWIND list as v
MATCH (n) WHERE left(n.name, size(v))=v return n

後方一致
UNWIND list as v
MATCH (n) WHERE right(n.name, size(v))=v return n

# Ki,Satで始まるnameを検索さんを検索
$ UNWIND ['Ki','Sat'] as v MATCH (n) WHERE left(n.name, size(v))=v RETURN n

関係データを取得

構文
MATCH (node1)-[:Relations]->(node2) return node1, node2

# Satoさんの友達を検索(Satoさんの友達はKimさんとAokiさん
$ MATCH (n1 {name:'Sato'})-[:friends]->(n2) return n2

# Satoさんと友達同士の人を検索(友達同士なのはKimさんだけ)
$ MATCH (n1 {name:'Sato'})-[:friends]->(n2)-[:friends]->(n1) return n1, n2

ノードの階層を指定
MATCH (node1)-[:Relation*1..3]-(node2)

# Kimさんの友達の友達の友達を取得
$ MATCH  (n1 {name:'Kim'})-[:friends*1..3]->(n2) RETURN n2

# Kimさんの友達の友達を友達と友達関係にある人物
$ MATCH  (n1 {name:'Kim'})-[:friends*1..3]->(n2)-[:friends*]->(n3)-[:friends*]->(n2) RETURN n3

データを更新

ノードのプロパティを更新
MATCH (node) SET node.field = value

# Endoさんの年齢を30に更新
$ MATCH (node {name:'Endo'}) SET node.age = 30 return node

# Endoさんの性別、女性を追加
$ MATCH (node {name:'Endo'}) SET node.sex= 'femaile' return node

ノードのラベルを更新
MATCH (node1) SET node1:Label

# AokiさんにStudentというラベルを追加
$ MATCH (node1 {name:'Aoki'}) SET node1:Student

リレーションの属性(情報)を更新
MATCH (node1)<-[r:Relations]->(node2) SET r.type = 'value'

# SatoさんとKimさんの関係が親密であるという情報(属性)を追加
$ MATCH (node1{name:'Sato'})<-[relation1:friends]->(node2{name:'Kim'}) SET relation1.type = "intimate"

データを削除

ノードを削除
MATCH (node1) DELETE node1

リレーションも含めて削除
MATCH (node1) DETACH DELETE node1

リレーションだけ削除
MATCH (node1)-[r:Relation] DELETE r

# 削除用のデータを作成
$ CREATE (n1 {test:'hogehoge'}) return n1
# テストデータを削除
$ MATCH (node) WHERE node.test='hogehoge' DELETE node RETURN node

csvファイルからデータ取りこみ

ファイル名:./csv/node.csv
※こんな感じのデータ
1,Taro,20
2,Hanako,18
3,Kenta,22
4,Namihei,58

LOAD CSV FROM './csv/node.csv' AS line CREATE (:Person { name: line[1], age: toInteger(line[2])})

csv読み込み

終わり

ドキュメントを参考にCRUDの使い方だけさらっと、それからリレーションの探索のところもさらっとやってみました。
前方(後方)一致検索について情報が載ってなかったのでメモです。
前方一致はともかく、後方一致や部分一致は検索が遅いであろうことは想像つきますので実用的ではないですが。

参考
neo4j chapter3.Docker

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2