GraphDBおためし(JanusGraph)🍯
GraphDBおためし(JanusGraph)
↓を参考に、JanusGraphでGraphDBを試してみる
環境はいつも通り
Windows (arm64) + WSL2 + Docker でやる
→メモリ9GBくらい食いつぶすので別環境にする
① docker-composeを構成する + コンテナ起動
参考ページのdocker-compose.ymlを参考に
services:
cassandra:
image: cassandra:3
container_name: test-cassandra
ports:
- "9042:9042"
- "9160:9160"
networks:
- test-nw
janusgraph:
image: docker.io/janusgraph/janusgraph:latest
container_name: test-janusgraph
environment:
JANUS_PROPS_TEMPLATE: cql
janusgraph.storage.hostname: test-cassandra
volumes:
- ./docker/graphdb:/docker-entrypoint-initdb.d
ports:
- "8182:8182"
networks:
- test-nw
networks:
test-nw:
一応確認
$ docker-compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
test-cassandra cassandra:3 "docker-entrypoint.s…" cassandra 49 seconds ago Up 48 seconds 7000-7001/tcp, 0.0.0.0:9042->9042/tcp, 7199/tcp, 0.0.0.0:9160->9160/tcp
test-janusgraph docker.io/janusgraph/janusgraph:latest "docker-entrypoint.s…" janusgraph 49 seconds ago Up 48 seconds 0.0.0.0:8182->8182/tcp
②Gremlinコンソールにつないでみる
$ docker-compose exec janusgraph ./bin/gremlin.sh
\,,,/
(o o)
-----oOOo-(3)-oOOo-----
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/opt/janusgraph/lib/log4j-slf4j-impl-2.23.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/opt/janusgraph/lib/logback-classic-1.2.13.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
plugin activated: tinkerpop.server
plugin activated: tinkerpop.tinkergraph
14:04:32 INFO org.apache.tinkerpop.gremlin.hadoop.jsr223.HadoopGremlinPlugin.getCustomizers - HADOOP_GREMLIN_LIBS is set to: /opt/janusgraph/lib
14:04:33 WARN org.apache.hadoop.util.NativeCodeLoader.<clinit> - Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
plugin activated: tinkerpop.hadoop
plugin activated: tinkerpop.spark
plugin activated: tinkerpop.utilities
plugin activated: janusgraph.imports
gremlin>
ここからは以下のページ参考にいろいろ試してみる
① 組み込みの練習用グラフを生成する
gremlin> graph = TinkerFactory.createModern()
==>tinkergraph[vertices:6 edges:6]
こんなグラフができたらしい
引用:https://tinkerpop.apache.org/docs/3.7.3/tutorials/getting-started/
② GraphTraveralSourceを取得する
グラフに対するクエリは、GraphTraveralSourceというインターフェース使って実行する(らしい)
gremlin> g = graph.traversal()
③ 色々試してみる ~ g.V() その1 ~
gremlin> g.V()
==>v[1]
==>v[2]
==>v[3]
==>v[4]
==>v[5]
==>v[6]
頂点(Vertex)を選択できる
gremlin> g.V(1,3,5)
==>v[1]
==>v[3]
==>v[5]
カッコ内はIDで、指定した頂点が取得できる。
g.V().values()で、頂点に設定されているプロパティを取得できる。
gremlin> g.V().values("name")
==>marko
==>vadas
==>lop
==>josh
==>ripple
==>peter
gremlin> g.V().values("name", "age")
==>marko
==>29
==>vadas
==>27
==>lop
==>josh
==>32
==>ripple
==>peter
==>35
g.V().valueMap() のほうがわかりやすい?
gremlin> g.V().valueMap()
==>[name:[marko],age:[29]]
==>[name:[vadas],age:[27]]
==>[name:[lop],lang:[java]]
==>[name:[josh],age:[32]]
==>[name:[ripple],lang:[java]]
==>[name:[peter],age:[35]]
③ 色々試してみる ~ g.V() その2 ~
絞り込みをしてみる
プロパティで絞り込み
hasを使うと、プロパティの情報をもとに要素を絞り込める。
gremlin> g.V().has("name", "marko")
==>v[1]
gremlin> g.V().has("name", "marko").valueMap()
==>[name:[marko],age:[29]]
gremlin>
hasの結果にvalueMapもできる
(C#のLinqみある使い方...)
ラベルで絞り込み
頂点のラベルが「person」のもので絞り込める。
gremlin> g.V().hasLabel("person").valueMap()
==>[name:[marko],age:[29]]
==>[name:[vadas],age:[27]]
==>[name:[josh],age:[32]]
==>[name:[peter],age:[35]]
id()にすれば、絞り込んだ頂点のidが取れる。
gremlin> g.V().hasLabel("person").id()
==>1
==>2
==>4
==>6
③ 色々試してみる ~ g.E() ~
Edge(辺)の話。とはいえ、Vertexと同じ感じっぽい。
gremlin> g.E()
==>e[7][1-knows->2]
==>e[8][1-knows->4]
==>e[9][1-created->3]
==>e[10][4-created->5]
==>e[11][4-created->3]
==>e[12][6-created->3]
EdgeId:7は、VertexId:1がVertexId:2を知っている 関係を表している。
valueMapを使えば、Edgeに設定されているプロパティが取得できる。
gremlin> g.E().valueMap()
==>[weight:0.5]
==>[weight:1.0]
==>[weight:0.4]
==>[weight:1.0]
==>[weight:0.4]
==>[weight:0.2]
重みの情報だけあるっぽい。
③ 色々試してみる ~ 走査 ~
頂点と辺で構成されるグラフをたどる:走査
頂点から出ている辺を取得
outE()
gremlin> g.V(1).outE()
==>e[9][1-created->3]
==>e[7][1-knows->2]
==>e[8][1-knows->4]
頂点1からは、辺9,7,8が出ている
辺の出元の頂点を取得
outV()
gremlin> g.E(12).outV()
==>v[6]
辺12の出元には頂点6がいる
頂点に入ってくる辺を取得
inE()
gremlin> g.V(3).inE()
==>e[9][1-created->3]
==>e[11][4-created->3]
==>e[12][6-created->3]
頂点3に入る辺は、辺9,11,12
辺の出先の頂点を取得
inV()
gremlin> g.E(12).inV()
==>v[3]
辺12の出先には頂点3がいる
頂点に対してつながってる辺
bothE()
gremlin> g.V(3).bothE()
==>e[9][1-created->3]
==>e[11][4-created->3]
==>e[12][6-created->3]
方向は不問
頂点に対してつながっている頂点
both()
gremlin> g.V(3).both()
==>v[1]
==>v[4]
==>v[6]
方向は不問
③ 色々試してみる ~ 経路 ~
それまでの走査でたどった経路を順に出力できる:path
gremlin> g.V(1).out().out()
==>v[5]
==>v[3]
gremlin> g.V(1).out().out().path()
==>[v[1],v[4],v[5]]
==>[v[1],v[4],v[3]]
↑頂点1の2つ先の頂点までたどった時の経路
繰り返しの書き方もあるらしい
gremlin> g.V(1).repeat(__.out()).times(2).path()
==>[v[1],v[4],v[5]]
==>[v[1],v[4],v[3]]
gremlin>
宿題
- データの追加/削除/更新を試したい
- Pythonとつなげてみたい