LoginSignup
1
1

More than 3 years have passed since last update.

JanusGraphのスキーマ① - Edge Label Multiplicity

Posted at

本当はスキーマ全体についての記事を書こうと思ったが、最初のEdge Label Multiplicityだけで文量が嵩みそうだったので、ひとまずこれだけを重点的に解説してみる。

例によって、英語が読めるなら公式のドキュメントに目を通すのをおススメする。
Schema and Data Modeling

Edge Label Multiplicity

エッジ(辺)のラベルについては、Multiplicity(多重度?)という設定を行うことができる。Multiplicityは5種類の中から1つ選択することができ、それぞれ制限の内容が異なる。制限に反する場合、エッジ登録時にエラーが発生して失敗する。

Multiplicity 説明
MULTI [デフォルト]一切の制限なし。あらゆる2頂点間について、方向、エッジ数ともに好きなだけエッジを張ることができる
SIMPLE 2頂点間のエッジについてはどちらの方向についても最大1本まで
MANY2ONE 頂点に入ってくる方向(incoming)については制限なし。出ていく方向(outgoing)については全ての頂点に対して合計1本まで
ONE2MANY 頂点から出ていく方向(outgoing)については制限なし。入ってくる方向(incoming)については全ての頂点に対して合計1本まで
ONE2ONE 頂点から出ていく方向は最大1本まで、頂点に入ってくる方向も最大1本まで

簡単な操作で試してみる。新規のデータベースを立ち上げた状態でGremlinコンソールからリモート接続する(参考)

gremlin> :remote connect tinkerpop.server conf/remote.yaml session
==>Configured localhost/127.0.0.1:8182-[f3e6dcfb-60ab-44d7-aaeb-0f26b01135cc]
gremlin> :> m = graph.openManagement()
==>org.janusgraph.graphdb.database.management.ManagementSystem@146ecc1c
gremlin> :> m.makeEdgeLabel("multi").multiplicity(Multiplicity.MULTI).make()
==>multi
gremlin> :> m.makeEdgeLabel("simple").multiplicity(Multiplicity.SIMPLE).make()
==>simple
gremlin> :> m.makeEdgeLabel("many2one").multiplicity(Multiplicity.MANY2ONE).make()
==>many2one
gremlin> :> m.makeEdgeLabel("one2many").multiplicity(Multiplicity.ONE2MANY).make()
==>one2many
gremlin> :> m.makeEdgeLabel("one2one").multiplicity(Multiplicity.ONE2ONE).make()
==>one2one
gremlin> :> m.commit()
==>null

以上のようにして、5種類それぞれのEdge Labelを登録する。printSchemaを実行すると、以下のような状態になっている。

gremlin> :> m = graph.openManagement()
==>org.janusgraph.graphdb.database.management.ManagementSystem@552c511a
gremlin> :> m.printSchema()
==>------------------------------------------------------------------------------------------------
Edge Label Name                | Directed    | Unidirected | Multiplicity                         |
---------------------------------------------------------------------------------------------------
multi                          | true        | false       | MULTI                                |
simple                         | true        | false       | SIMPLE                               |
many2one                       | true        | false       | MANY2ONE                             |
one2many                       | true        | false       | ONE2MANY                             |
one2one                        | true        | false       | ONE2ONE                              |
---------------------------------------------------------------------------------------------------

さらに、グラフに4つほど確認用の頂点を追加する。

:> bob = g.addV("person").property("name", "bob").next()
==>v[4136]
:> james = g.addV("person").property("name", "james").next()
==>v[4184]
:> alice = g.addV("person").property("name", "alice").next()
==>v[8232]
:> ellie = g.addV("person").property("name", "ellie").next()
==>v[4152]

これらに対して、エッジを作成してみる。

MULTI

janusgraph_schema1_01.png

gremlin> :> g.addE("multi").from(bob).to(alice)
==>e[2rp-36w-6c5-6co][4136-follow->8232]
gremlin> :> g.addE("multi").from(bob).to(alice)
==>e[35x-36w-6c5-6co][4136-follow->8232]

自由にエッジを張ることができる。当然だが、同じ2頂点間に複数エッジを張っても問題ない。

SIMPLE

janusgraph_schema1_02.png

gremlin> :> g.addE("simple").from(bob).to(alice)
==>e[4qt-36w-1lh-6co][4136-simple->8232]
gremlin> :> g.addE("simple").from(bob).to(alice)
An edge with the given label already exists between the pair of vertices and the label [simple] is simple
Type ':help' or ':h' for help.
Display stack trace? [yN]

同じ2頂点間に複数張ろうとするとエラーになった。Already Existsと怒られた。

gremlin> :> g.addE("simple").from(alice).to(bob)
==>e[551-6co-1lh-36w][8232-simple->4136]
gremlin> :> g.addE("simple").from(alice).to(bob)
An edge with the given label already exists between the pair of vertices and the label [simple] is simple
Type ':help' or ':h' for help.
Display stack trace? [yN]

向きを逆にして(aliceとbobを入れ替えて)も同じようにエラーとなる。

MANY2ONE

janusgraph_schema1_03.png

MANY2ONESIMPLEの制限を含みつつ、さらに厳しい。

gremlin> :> g.addE("many2one").from(bob).to(alice)
==>e[5j9-36w-2dx-6co][4136-many2one->8232]
gremlin> :> g.addE("many2one").from(bob).to(ellie)
An edge with the given label already exists on the out-vertex and the label [many2one] is out-unique
Type ':help' or ':h' for help.
Display stack trace? [yN]
gremlin> :> g.addE("many2one").from(james).to(alice)
==>e[1l7-388-2dx-6co][4184-many2one->8232]
gremlin> :> g.addE("many2one").from(james).to(ellie)
An edge with the given label already exists on the out-vertex and the label [many2one] is out-unique
Type ':help' or ':h' for help.
Display stack trace? [yN]

1本目は問題ないが、2本目は違う頂点に対して張ろうとしてもエラーになる。エラーメッセージのout-uniqueが言うとおりに、頂点から出る矢印は1本に限られる。

ONE2MANY

janusgraph_schema1_04.png

MANY2ONEもまた、SIMPLEの制限を含みつつ、さらに厳しい。

gremlin> :> g.addE("one2many").from(alice).to(bob)
==>e[5xh-6co-36d-36w][8232-one2many->4136]
gremlin> :> g.addE("one2many").from(ellie).to(bob)
An edge with the given label already exists on the in-vertex and the label [one2many] is in-unique
Type ':help' or ':h' for help.
Display stack trace? [yN]
gremlin> :> g.addE("one2many").from(alice).to(james)
==>e[6bp-6co-36d-388][8232-one2many->4184]
gremlin> :> g.addE("one2many").from(ellie).to(james)
An edge with the given label already exists on the in-vertex and the label [one2many] is in-unique
Type ':help' or ':h' for help.
Display stack trace? [yN]

ある頂点から、それぞれ違う頂点に対して、何本張っても問題はない。ただし、同じ頂点に対して2本目を張ることは出来ない。エラーメッセージのin-uniqueが言うとおりに、頂点に入ってくる矢印は1本に限られる。

ONE2ONE

janusgraph_schema1_05.png

ONE2ONEは最も重い制限である。MANY2ONEONE2MANY両方の条件を課される。

gremlin> :> g.addE("one2one").from(bob).to(alice)
==>e[6px-36w-3yt-6co][4136-one2one->8232]
gremlin> :> g.addE("one2one").from(alice).to(james)
==>e[745-6co-3yt-388][8232-one2one->4184]
gremlin> :> g.addE("one2one").from(james).to(ellie)
==>e[1zf-388-3yt-37c][4184-one2one->4152]
gremlin> :> g.addE("one2one").from(ellie).to(alice)
An edge with the given label already exists on the in-vertex and the label [one2one] is in-unique
Type ':help' or ':h' for help.
Display stack trace? [yN]

入ってくるのも1本まで、出ていくのも1本までという、シンプルな形のグラフとなる(線形リストとか、環状ループとか)。

選択方針

不都合がない範囲で、なるべく厳しい制限を課すように設定するのが良い。データ入力時に誤ったエッジを入力してしまうミスを少しだけでも減らすことができる。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1