Open12

GraphDBおためし(JanusGraph)🍯

もももも

① docker-composeを構成する + コンテナ起動

参考ページのdocker-compose.ymlを参考に

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> 
もももも

② 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とつなげてみたい