Gremlin ConsoleのGroovyを使用したグラフ・データベース・スキーマの作成。
グラフ・データベースのデータ・モデルの作成は、スキーマを作成するための重要な最初のステップです。データ・モデルを設計し、グラフを作成した後、グラフ・データベースの作成における次のステップは、頂点および辺ならびにそのプロパティのスキーマの定義です。Gremlin-Groovyは、Apache TinkerPop Gremlin Consoleにパッケージ化されています。Gremlin-Groovyを使用してGremlinコマンドを含むスクリプトを作成するか、Gremlin Consoleに直接コマンドを入力します。
手順
-
Gremlin Consoleを起動します。
-
データを格納する新しいグラフを作成し、クエリーを実行するためのグラフ探索に別名を作成します。以前作成したグラフを再利用する場合は、グラフ・スキーマおよびデータを削除します。
-
リモートGremlin Serverで、
timeout
値をmax
に設定します。スクリプト処理を必ず完了するには、この設定を使用します。
gremlin> :remote config timeout max
-
スキーマを作成するスクリプトは、このページの下の例で示します。スクリプト・ファイルは、リモートGremlin Serverに読み込まれ、実行されます。クイック・スタートのスクリプトを以前に実行したことがある場合には、グラフからそのスキーマおよびデータを消去しない限り、このスクリプトは機能しません。
gremlin> :load /tmp/RecipeSchema.groovy
-
以下の各ステップでは、スクリプト全体をセクションごとに分けて詳細を説明します。
-
頂点および辺のプロパティを定義します。キー名に加えて、プロパティのデータ型を指定します。この例で作成するすべてのプロパティは、Text、Integers、またはTimestampsです。その他のデータ型も使用できます。プロパティは、グラフの選択的サブセットの取得または格納値の取得に使用します。プロパティは本来グローバルであり、頂点ラベルおよびプロパティのペアは、探索で使用するプロパティを一意に識別します。辺プロパティは削除および再利用されるため、更新の負荷が高くなります。辺プロパティは、使用が必要な場合に使用してください。
// プロパティ・キー
// ifNotExists()を使用して、作成済みのプロパティ・キーがあるかどうかを確認します。
schema.propertyKey('name').Text().ifNotExists().create()
schema.propertyKey('gender').Text().create()
schema.propertyKey('instructions').Text().create()
schema.propertyKey('category').Text().create()
schema.propertyKey('year').Int().create()
schema.propertyKey('timestamp').Timestamp().create()
schema.propertyKey('ISBN').Text().create()
schema.propertyKey('calories').Int().create()
schema.propertyKey('amount').Text().create()
schema.propertyKey('stars').Int().create()
// single()はオプションです(デフォルトのため)
schema.propertyKey('comment').Text().single().create()
// 複数の値を指定できる複数プロパティの例
// 次の4行は2つのプロパティを定義した後、'country'に対するメタプロパティ'livedIn'を作成します
//メタプロパティとは、プロパティのプロパティです
// 例:'livedIn':'1999-2005' 'country':'Belgium'
// schema.propertyKey('nickname').Text().multiple().create()
// schema.propertyKey('country').Text().create()
// schema.propertyKey('livedIn').Text().create()
// schema.propertyKey('country').Text().properties('livedIn').create()
ifNotExists()
を使用して、プロパティ・キーがすでに存在しているかどうかをチェックできます。プロパティ・キーは、1つまたは複数のカーディナリティを使用して作成できます。デフォルトは、1つのカーディナリティで、指定は省略できます。メタプロパティ、またはプロパティのプロパティは、propertyKey()
、properties()
の順に使用して作成できます。メタプロパティを作成するには、プロパティ・キーが存在していることが必要です。
-
頂点ラベルを定義します。頂点ラベルは、作成できる頂点の型を識別します。
/// 頂点ラベル
schema.vertexLabel('author').ifNotExists().create()
schema.vertexLabel('recipe').create()
// プロパティを含む頂点ラベルの作成例
// schema.vertexLabel('recipe').properties('name','instructions').create()
schema.vertexLabel('ingredient').create()
schema.vertexLabel('book').create()
schema.vertexLabel('meal').create()
schema.vertexLabel('reviewer').create()
// カスタム頂点IDの例:
// schema.propertyKey('city_id').Int().create()
// schema.propertyKey('sensor_id').Uuid().create()
// schema().vertexLabel('FridgeSensor').partitionKey('city_id').clusteringKey('sensor_id').create()
ifNotExists()
を使用すると、頂点ラベルが前に存在しているかをチェックできます。頂点ラベルは、プロパティとともに作成できます。頂点ラベルは、標準の頂点IDではなく、カスタム頂点IDとともに作成できます。
-
辺ラベルを定義します。辺ラベルは、作成できる辺のタイプを識別します。
// 辺ラベル
schema.edgeLabel('authored').ifNotExists().create()
schema.edgeLabel('created').create()
schema.edgeLabel('includes').create()
schema.edgeLabel('includedIn').create()
schema.edgeLabel('rated').connection('reviewer','recipe').create()
ifNotExists()
を使用すると、辺ラベルが前に存在しているかをチェックできます。辺ラベルは、connection()を使用して識別される隣接頂点ラベルとともに作成できます。
-
クエリー処理を高速化できるインデックスを定義します。ここでは、インデックスのすべての型を示します。
// 頂点インデックス
// 二次インデックス
schema.vertexLabel('author').index('byName').secondary().by('name').add()
// マテリアライズド・インデックス
schema.vertexLabel('recipe').index('byRecipe').materialized().by('name').add()
schema.vertexLabel('meal').index('byMeal').materialized().by('name').add()
schema.vertexLabel('ingredient').index('byIngredient').materialized().by('name').add()
schema.vertexLabel('reviewer').index('byReviewer').materialized().by('name').add()
// サーチ
// schema.vertexLabel('recipe').index('search').search().by('instructions').asText().add()
// schema.vertexLabel('recipe').index('search').search().by('instructions').asString().add()
// 複数のプロパティ・キーにサーチ・インデックスが付いている場合
// schema.vertexLabel('recipe').index('search').search().by('instructions').asText().by('category').asString().add()
// 辺インデックス
schema.vertexLabel('reviewer').index('ratedByStars').outE('rated').by('stars').add()
// メタプロパティ'livedIn'を使用したプロパティ・インデックスの例:
// schema().vertexLabel('author').index('byLocation').property('country').by('livedIn').add()
-
グラフ・スキーマを作成した後、確認のためにそのスキーマを検証します。このコマンドは、フル・スクリプトの最後のコマンドとして含まれています。
==>schema.propertyKey("member_id").Smallint().single().create()
schema.propertyKey("instructions").Text().single().create()
schema.propertyKey("amount").Text().single().create()
schema.propertyKey("gender").Text().single().create()
schema.propertyKey("year").Int().single().create()
schema.propertyKey("calories").Int().single().create()
schema.propertyKey("stars").Int().single().create()
schema.propertyKey("community_id").Int().single().create()
schema.propertyKey("ISBN").Text().single().create()
schema.propertyKey("name").Text().single().create()
schema.propertyKey("comment").Text().single().create()
schema.propertyKey("category").Text().single().create()
schema.propertyKey("timestamp").Timestamp().single().create()
schema.edgeLabel("authored").multiple().create()
schema.edgeLabel("rated").multiple().properties("stars").create()
schema.edgeLabel("includedIn").multiple().create()
schema.edgeLabel("created").multiple().create()
schema.edgeLabel("includes").multiple().create()
schema.vertexLabel("meal").properties("name").create()
schema.vertexLabel("meal").index("byMeal").materialized().by("name").add()
schema.vertexLabel("ingredient").properties("name").create()
schema.vertexLabel("ingredient").index("byIngredient").materialized().by("name").add()
schema.vertexLabel("author").properties("name").create()
schema.vertexLabel("author").index("byName").secondary().by("name").add()
schema.vertexLabel("book").create()
schema.vertexLabel("recipe").properties("name").create()
schema.vertexLabel("recipe").index("byRecipe").materialized().by("name").add()
schema.vertexLabel("reviewer").properties("name").create()
schema.vertexLabel("reviewer").index("byReviewer").materialized().by("name").add()
schema.vertexLabel("reviewer").index("ratedByStars").outE("rated").by("stars").add()
schema.edgeLabel("rated").connection("recipe", "reviewer").connection("reviewer", "recipe").add()
例
// レシピ・スキーマ
// Studioで実行する場合は、すべての行をセルにコピー&ペーストしてから実行します。
// Gremlin Consoleで実行する場合は、loadコマンドを使用します
// :load /tmp/RecipeSchema.groovy
// プロパティ・キー
// ifNotExists()を使用して、作成済みのプロパティ・キーがあるかどうかを確認します。
schema.propertyKey('name').Text().ifNotExists().create()
schema.propertyKey('gender').Text().create()
schema.propertyKey('instructions').Text().create()
schema.propertyKey('category').Text().create()
schema.propertyKey('year').Int().create()
schema.propertyKey('timestamp').Timestamp().create()
schema.propertyKey('ISBN').Text().create()
schema.propertyKey('calories').Int().create()
schema.propertyKey('amount').Text().create()
schema.propertyKey('stars').Int().create()
// single()はオプションです(デフォルトのため)
schema.propertyKey('comment').Text().single().create()
// 複数の値を指定できる複数プロパティの例
// 次の4行は2つのプロパティを定義した後、'country'に対するメタプロパティ'livedIn'を作成します
//メタプロパティとは、プロパティのプロパティです
// 例:'livedIn':'1999-2005' 'country':'Belgium'
// schema.propertyKey('nickname').Text().multiple().create()
// schema.propertyKey('country').Text().create()
// schema.propertyKey('livedIn').Text().create()
// schema.propertyKey('country').Text().properties('livedIn').create()
// 頂点ラベル
schema.vertexLabel('author').ifNotExists().create()
schema.vertexLabel('recipe').create()
// プロパティを含む頂点ラベルの作成例
// schema.vertexLabel('recipe').properties('name','instructions').create()
schema.vertexLabel('ingredient').create()
schema.vertexLabel('book').create()
schema.vertexLabel('meal').create()
schema.vertexLabel('reviewer').create()
// カスタム頂点IDの例:
// schema.propertyKey('city_id').Int().create()
// schema.propertyKey('sensor_id').Uuid().create()
// schema().vertexLabel('FridgeSensor').partitionKey('city_id').clusteringKey('sensor_id').create()
// 辺ラベル
schema.edgeLabel('authored').ifNotExists().create()
schema.edgeLabel('created').create()
schema.edgeLabel('includes').create()
schema.edgeLabel('includedIn').create()
schema.edgeLabel('rated').connection('reviewer','recipe').create()
// 頂点インデックス
// 二次インデックス
schema.vertexLabel('author').index('byName').secondary().by('name').add()
// マテリアライズド・インデックス
schema.vertexLabel('recipe').index('byRecipe').materialized().by('name').add()
schema.vertexLabel('meal').index('byMeal').materialized().by('name').add()
schema.vertexLabel('ingredient').index('byIngredient').materialized().by('name').add()
schema.vertexLabel('reviewer').index('byReviewer').materialized().by('name').add()
// サーチ
// schema.vertexLabel('recipe').index('search').search().by('instructions').asText().add()
// schema.vertexLabel('recipe').index('search').search().by('instructions').asString().add()
// 複数のプロパティ・キーにサーチ・インデックスが付いている場合
// schema.vertexLabel('recipe').index('search').search().by('instructions').asText().by('category').asString().add()
// 辺インデックス
schema.vertexLabel('reviewer').index('ratedByStars').outE('rated').by('stars').add()
// メタプロパティ'livedIn'を使用したプロパティ・インデックス:
schema.vertexLabel('author').index('byLocation').property('country').by('livedIn').add()
// スキーマの説明
// スキーマが目的通りに構築されているかどうかをチェックするために使用します
schema.describe()