グラフDBを操作する言語「Gremlin」さんを使ってDB操作をしてみる。
Gremlinさんキャラがきもかわいい。たまに変な服着てるところがきもかわいい。
Gremlin - orient - Using Gremlin with OrientDB
Home · tinkerpop/gremlin Wiki · GitHub
OrientDBには標準でこのGremlinがついてます。
他にもNeo4jとかでも使えるっぽいので、グラフDB触るなら覚えておいた方がいいのかもしれない。
何はともあれ触ってみないと分からんので触ってみます。
$ ./gremlin.sh \,,,/ (o o) -----oOOo-(_)-oOOo----- 2012/04/13 14:43:35 java.util.prefs.FileSystemPreferences$2 run 情報: Created user preferences directory.
きもい。きもいよGremlinさん。
サイトのちょっとかわいい感じはどこにいってしまったんだよ。
いきなりきもいものが出てきて若干やる気が削がれましたが頑張って続けます。
ざっくり眺めた感じ、DB的にはgraphがひとつのDB、vertexがedgeがそれぞれテーブルみたいな形で保持されるみたい。
グラフDB的にはgraphは言わずもがなvertex(頂点)とedge(線)の集合みたいな。vertexをedgeで繋ぐことでgraphができるみたいな。なんか。そんなかんじの。
というわけで早速グラフを作ってみます。
gremlin> g = new OrientGraph('local:../databases/graph1'); ==>orientgraph[local:../databases/graph2]
できたっぽい。OrientDBのホームディレクトリにdatabases/graph1が作成されてました。
既に同じパスで作成されていた場合は作らずに繋ぐだけになるみたい。
別サーバに繋ぐ場合は以下のような形式で。
gremlin> g = new OrientGraph('remote:$サーバIP$/graph1');
次にvertexを作ってみる。
v1 = g.addVertex(); ==>v[#6:0]
なんかよくわかんないけど出来たみたい。
「6:0」がこいつに振られたIDみたいです。
これだけ作ってもなんかよくわかんないので、vertexにプロパティを追加します。
gremlin> v1.name = 'user1' ==>user1
vertex作成の時点でプロパティを追加することもできます。
gremlin> g.addVertex([name:'user2']); ==>v[#6:1]
中身の確認は以下のような形式で出来ます。
gremlin> v1.name ==>user1 gremlin> v1.map ==>{name=user1}
graphからvertexを参照する場合は以下のような形でIDを指定します。
gremlin> g.v('6:0'); ==>v[#6:0] gremlin> g.v('6:0').map; ==>{name=user1}
変数に代入する場合とかもこの形式で。
vertexを消す場合は以下のような感じです。
gremlin> g.removeVertex(g.v('6:2')); ==>null
graphに存在する全てのvertexを見る場合は以下のような感じで。
gremlin> g.V ==>v[#6:0] ==>v[#6:1]
次にvertexをedgeで繋いでみます。
gremlin> g.addEdge(v1, v2, 'follow'); ==>e[#7:0][#6:0-follow->#6:1]
この例では、v1とv2が「follow」という関係で繋がったことになります。
この値はlabelと言い、例えば「v1が」「follow」しているvertexを探すといった操作をするときに使用できます。
以下のようなかんじで。
gremlin> v1.outE.filter{it.label=='follow'} ==>e[#7:1][#6:0-follow->#6:1] ==>e[#7:3][#6:0-follow->#6:4]
この場合、v1から外に伸びているedgeで、「follow」というlabelがついているものだけを抽出します。
また、edgeもvertexと同じくプロパティを持つことが出来ます。
gremlin> e1= g.addEdge(v1, v2, 'follow', [date:'2012-04-13']); ==>e[#7:0][#6:0-follow->#6:1] gremlin> e1.date ==>2012-04-13
次にedgeを持つvertexを消してみます。
希望としてはvertexが消えたらそこに紐づくedgeも消えて欲しいところですが果たして。
gremlin> g.removeVertex(g.v('6:2')); ==>null gremlin> g.E ==>e[#7:0][#6:0-follow->#6:1]
どうやら希望通りの挙動をしているようです。すてきね。
既に同じ方向、同じlabelのedgeを持つvertexを重複して同じedgeで繋ぐこともできちゃうみたい。
あと同じvertexを繋ぐことも出来てしまう…このへんどっかで制御できるのかなー。
上の方で「graphがひとつのDB、vertexがedgeがそれぞれテーブル」みたいなことを書いたんですが、GremlinじゃなくてOrientDB標準のコンソールに入って今作ったgraphがどうなるか確認してみると、以下のような感じになってます。
> select from ographedge ---+---------+--------------------+--------------------+-------------------- #| RID |out |in |label ---+---------+--------------------+--------------------+-------------------- 0| #7:0|#6:0 |#6:1 |follow 1| #7:1|#6:1 |#6:0 |follow 2| #7:2|#6:2 |#6:0 |follow 3| #7:3|#6:3 |#6:0 |follow 4| #7:4|#6:4 |#6:0 |follow 5| #7:5|#6:0 |#6:2 |follow 6| #7:6|#6:1 |#6:2 |follow 7| #7:7|#6:0 |#6:3 |follow ---+---------+--------------------+--------------------+-------------------- 8 item(s) found. Query executed in 0.014 sec(s). > select from ographvertex ---+---------+--------------------+--------------------+-------------------- #| RID |name |out |in ---+---------+--------------------+--------------------+-------------------- 0| #6:0|user1 |[3] |[4] 1| #6:1|user1 |[2] |[1] 2| #6:2|user3 |[1] |[2] 3| #6:3|user4 |[1] |[1] 4| #6:4|user5 |[1] |null 5| #6:5|user6 |null |null 6| #6:6|user7 |null |null 7| #6:7|user8 |null |null 8| #6:8|user9 |null |null 9| #6:9|user10 |null |null ---+---------+--------------------+--------------------+-------------------- 10 item(s) found. Query executed in 0.025 sec(s).
なるほどなー。
とりあえず作ったり繋いだりは出来るようになりましたが、実際にサービスで利用する場合の抽出方法などがいまいちイメージできてないので、次はそこを。
Gremlinさんむずかしいよ。きもかわいいよ。シェル上ではきもいよ。