TinkerPopフレームワークのGremlinコンソールについての豆知識をまとめておきます。
コマンド
:help
Gremlinコンソールで何ができるかについては:help
または?
で一覧が表示される
:remote
Gremlinサーバーに接続するには:remote
を使う。基本的には以下のコマンドを丸暗記すればよい。
gremlin> :remote connect tinkerpop.server conf/remote.yaml [session|session-managed]
サーバーのドメインやポート番号を変えた場合はconf/remote.yamlをコピーして書き換えたものを使う。
末尾にsession
をつけるとリモートコマンドの結果を変数として受け取ることができる。つけないとコマンド実行毎に環境がリセットされる。ただし、session
を付けた場合他プロセスからのグラフ変更が出来なくなる(ロックされる?)ことに注意。グラフの操作に慣れたらもう付けない方がいい。
[2020/04/28加筆]
:remoteコマンド末尾にはsession
またはsession-managed
オプションを付け加えることができる。これらの効果について以下に示す。
未指定(セッションレス)
オプションを指定しない場合はセッションレス接続となる。コンソール上で1つ命令を送信するたびにトランザクションが開始され、コミットされる。すなわち、addVertex
やaddV
のようなグラフに対する変更は都度自動的にコミットされる。また、1命令ごとに環境がリセットされるため、変数を持つことが出来ない。すなわち、戻り値を受け取るようなコードを記述しても、戻り値は消失するため使用することは出来ない。
session
オプションsession
を指定した場合はセッションモードになる。トランザクションは自分で管理する必要がある。すなわち、グラフに対する変更は自分でコミットしない限り反映されない。その一方で、ロールバックを行うことも可能なので、自由度が高い。セッションが継続している間は変数が保持されるため、命令の戻り値を使用することができる。
session-managed
オプションsession-managed
を指定した場合はセッションモードになる。session
との違いは、セッションレスの場合と同様に1つ命令を送信するたびにトランザクションの開始とコミットが行われる点である。セッションが継続している間は変数が保持されるため、セッションレスの場合よりは融通が利く。
オプション | トランザクション | 変数 |
---|---|---|
未指定 | 自動 | 保持されない |
session | 手動 | 保持される |
session-managed | 自動 | 保持される |
:exit
Gremlinコンソールを閉じる
:load
指定したスクリプトファイルに記述されたコマンドを1行ずつ順に実行する。
gremlin> :load sample.groovy
グラフの生成
練習用あるいは解析用のグラフを生成する方法はいくつかある。
TinkerGraph
空のグラフを作るにはopen
関数を用いる
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
TinkerFactory
TinkerPopのチュートリアル用グラフファクトリー
以下の5種類のグラフ生成関数がある。
関数名 | 説明 | 図 |
---|---|---|
createModern() | チュートリアル用グラフ(TinkerPop ver3以降) 頂点数6辺数6 |
リンク 画像直 |
createClassic() | チュートリアル用グラフ(TinkerPop ver2以前)※仕様が古く、頂点ラベルを持たない。今からあえて使う理由はない | |
createKitchenSink() | 検証用グラフ。自己ループを持つ頂点を含む。 頂点数3辺数3 |
なし |
createTheCrew() | チュートリアル用グラフ。createModernより情報が多いバージョン 頂点数6辺数14 |
リンク 画像直 |
createGratefulDead() | ロックバンド・グレイトフルデッドのシングル曲データを格納したグラフ。頂点数808辺数8049 | なし |
gremlin> graph = TinkerFactory.createModern()
==>tinkergraph[vertices:6 edges:6]
gremlin> graph = TinkerFactory.createTheCrew()
==>tinkergraph[vertices:6 edges:14]
gremlin> graph = TinkerFactory.createGratefulDead()
==>tinkergraph[vertices:808 edges:8049]
また、generate*
関数を用いると、既存のグラフに対してデータを挿入することができる。
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> TinkerFactory.generateModern(graph)
==>null
gremlin> graph
==>tinkergraph[vertices:6 edges:6]
Groovyリフレクション
オブジェクトの型やメソッドが分かるとクエリの動作の理解に役立つ。
クラス名の取得
gremlin> graph.class // 変数名.classでクラス名を取得できる
==>class org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph
クラス名 javadoc current
でググれば最新版JavaDocのページに辿り着ける。クラス名.java
で検索するとgithubのページ(実装ソースコード)に辿り着ける。地味に役立つ。
メソッド一覧の取得
gremlin> graph.class.methods // 変数名.class.methodsでメソッド一覧を取得できる
==>public java.lang.String org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph.toString()
==>public void org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph.clear()
==>public void org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph.close()
==>public org.apache.tinkerpop.gremlin.process.computer.GraphComputer org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph.compute()
==>public org.apache.tinkerpop.gremlin.process.computer.GraphComputer org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph.compute(java.lang.Class)
...
正直読みにくいので使いどころはあまりない。
その他
リモートコマンドの戻り値をローカルで使う
リモートコマンドの結果は、ローカルのresult
という変数に格納されている。
gremlin> :> g.V().values("name")
==>marko
==>bob
gremlin> result
==>result{object=marko class=java.lang.String}
==>result{object=bob class=java.lang.String}
gremlin> result[0]["object"]
==>marko
gremlin> result[1]["object"]
==>bob
使うかと言えば使わない……。
自動Terminal-Step実行を阻止
Gremlinコンソール上でクエリを実行すると、自動的にTerminal-Stepsを送ってクエリが完了してしまう。それが嫌で、クエリを作るだけに留めたい場合は以下のようにする。
gremlin> query = g.V(); null // クエリを作る(実行はしない)
==>null
gremlin> vertices = query.toList(); null // クエリを実行して結果を得る
==>null
gremlin> vertices // 結果を確認する
==>v[1]
==>v[2]
==>v[3]
==>v[4]
==>v[5]
==>v[6]
コマンドの戻り値がGraphTraversal系の型だと、自動的にTerminal-Stepsを実行してしまうので、セミコロンで区切った後で、nullを評価するようにすると、Terminal-Steps実行は行われない。Gremlinコンソール上でTerminal-Stepsの動きを勉強する際にしか役に立たない情報だが、個人的には一応役に立ったので記しておく。