gremlinpythonの使い方覚書

# 記事の内容
GraphDBであるGremlinをPythonで使ってみました。
使い方をメモします

# ライブラリの準備
GremlinをPythonで扱うためのライブラリをインストールします

~~~
pip install gremlinpython
~~~

# 実装
## ライブラリのインポート

~~~ .py
from gremlin_python import statics
from gremlin_python.structure.graph import Graph
from gremlin_python.process.graph_traversal import __
from gremlin_python.process.strategies import *
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
~~~

##　コネクションの作成
~~~ .py
graph = Graph()

# Gremlinのコネクション作成
g = graph.traversal().withRemote(DriverRemoteConnection('ws://localhost:8182/gremlin','g'))
~~~
DriverRemoteConnectionの第一引数でGremlinサーバーの情報を渡す
第二引数では"g"を渡しているが、この"g"が何を指しているのかは不明
サーバー起動時に以下のログが出力されており、この"g"だと思われる。

~~~
[INFO] ServerGremlinExecutor - A GraphTraversalSource is now bound to [g] with graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
~~~
何らかの設定ファイルで変更出来そうな気がするが、現時点でそこまでは調べることが出来ていない。

## データ登録
データ登録をして、登録したデータを取得してみる

~~~ .py
g.addV('tarouo').property('name', 'tarou').toSet()
g.addV('tarouo').property('name', 'kotarou').toSet()
name = g.V().has('name', 'tarou').valueMap().toList()
print(name)
~~~
結果

~~~
[{'name': ['tarou']}]
~~~
取得結果はdictで返ってくる。何故か登録したnameはlist形式
データの取得は部分一致ではなく完全一致

## プロパティの追加
登録したデータにプロパティを追加する

### 1項目追加
~~~ .py
tarou = g.V().has('name', 'tarou').toList()[0]
g.V(tarou).property('from', 'Tokyo').toSet()
tarou = g.V(tarou).valueMap().toList()[0]
print(tarou)
~~~
結果

~~~
{'name': ['tarou'], 'from': ['Tokyo']}
~~~

### 複数項目追加
~~~ .py
g.V(tarou).property('from', 'Tokyo').property('age', 20).toSet()
tarou = g.V(tarou).valueMap().toList()[0]
print(tarou)
~~~
結果

~~~
{'name': ['tarou'], 'from': ['Tokyo'], 'age': [20]}
~~~
.property()を繋げることで複数項目追加することが可能

### 更新
既に登録済みのプロパティを別の値で登録すると更新される

~~~ .py
g.V(tarou).property('from', 'Kanagawa').property('age', 30).toSet()
tarou = g.V(tarou).valueMap().toList()[0]
print(tarou)
~~~
## プロパティの削除
出来そうな感じがするがやり方分からず・・。
やり方が判明したら更新します。

## データ削除
~~~
g.V().drop()
g.E().drop()
g.V().drop().iterate()
g.E().drop().iterate()
~~~
iterate無しだと最初の１件が削除される。
iterate有りだと全て削除される。

## エッジの追加
tarouとkotarouにエッジを追加します

~~~ .py
tarou = g.V().has('name', 'tarou').toList()[0]
kotarou = g.V().has('name', 'kotarou').toList()[0]
g.addE('follow').from_(tarou).to(kotarou).toSet()
edgeList = g.E().toList()
for edge in edgeList:
    print(edge)
~~~
結果

~~~
e[267][259-follow->261]
~~~
ID259とID261がfollowの関係で繋がっていることが取得できました。

~~~ .py
tarou = g.V().has('name', 'tarou').toList()[0]
kotarou = g.V().has('name', 'kotarou').toList()[0]
magotarou = g.V().has('name', 'magotarou').toList()[0]
g.addE('son').from_(tarou).to(kotarou).toSet()
g.addE('son').from_(kotarou).to(magotarou).toSet()
g.addE('grandchild').from_(tarou).to(magotarou).toSet()
~~~
こんな感じでエッジを追加できる

~~~
e[298][288-son->290]
e[299][290-son->292]
e[300][288-grandchild->292]
~~~

## エッジの情報を取得する
### 特定の点と関係があるリスト（値）を取得
~~~ .py
valueList = g.V(tarou).both().valueMap(True).toList()
for value in valueList:
    print(value)
~~~
結果

~~~
{<T.id: 1>: 498, <T.label: 4>: 'kotarou', 'name': ['kotarou']}
{<T.id: 1>: 500, <T.label: 4>: 'magotarou', 'name': ['magotarou']}
~~~
tarouと関係を設定しているkotarouとmagotarouの情報を取得出来ました。
### valueMapの引数を設定しない
Trueを設定しないと最低限のデータだけになります。

~~~
{'name': ['kotarou']}
{'name': ['magotarou']}
~~~

### 特定の点と関係があるリスト（エッジ）を取得
~~~
g.V(tarou).bothE()
g.V(tarou).bothE().valueMap().toList()
g.V(tarou).bothE().valueMap(True).toList()
~~~
三種類のやり方で取得してみます

~~~
# edge list 1..
e[597][587-son->589]
e[599][587-grandchild->591]
# edge list 2..
{}
{}
# edge list 3..
{<T.id: 1>: 597, <T.label: 4>: 'son'}
{<T.id: 1>: 599, <T.label: 4>: 'grandchild'}
~~~
一応、取得出来ました。
g.V()はValue関係の操作だと思ったので、g.E()でエッジ関係のデータを取得出来るのかなと思ったのですが、上手く取得出来ませんでした。

# おわりに
ネットワーク分析に使えるかなと思いGremlinの使い方を少し調べていたのですが、GraphDBの概念を理解しないとやはり難しいなという印象を受けました。
記載した内容以外にも面白い使い方が分かれば記事を更新していこうと思います。