Gremlin Consoleによるスキーマの作成

Gremlin ConsoleのGroovyを使用したグラフ・データベース・スキーマの作成。

グラフ・データベースのデータ・モデルの作成は、スキーマを作成するための重要な最初のステップです。データ・モデルが指定され、グラフが作成されたら、グラフ・データベース作成の次のステップは、頂点とエッジおよびそのプロパティのスキーマを定義することです。Gremlin-Groovyは、Apache TinkerPop Gremlin Consoleにパッケージ化されています。Gremlin-Groovyを使用してGremlinコマンドを含むスクリプトを作成するか、Gremlin Consoleに直接コマンドを入力します。

手順

  1. Gremlin Consoleを起動します
  2. データを格納する新しいグラフを作成し、クエリーを実行するためのグラフ探索に別名を作成します。以前に作成したグラフを再利用する場合は、グラフ・スキーマおよびデータを削除します
  3. リモートGremlin Serverで、timeout値をmaxに設定します。スクリプト処理を必ず完了するには、この設定を使用します。
    gremlin> :remote config timeout max
  4. スキーマを作成するスクリプトは、このページの下の例で示します。スクリプト・ファイルは、リモートGremlin Serverに読み込まれ、実行されます。クイック・スタートのスクリプトを以前に実行したことがある場合には、グラフからそのスキーマおよびデータを消去しない限り、このスクリプトは機能しません。
    gremlin> :load /tmp/RecipeSchema.groovy
  5. 以下のステップは、複数のセクションに分割されたスクリプト全体の詳細を示しています。
  6. 頂点とエッジのプロパティを定義します。プロパティのデータ型がキー名に加えて指定されます。この例で作成されるプロパティは、テキスト、整数、タイムスタンプのいずれかです。その他のデータ型も使用できます。プロパティは、グラフの選択的サブセットを取得し、格納された値を取得するために使用されます。プロパティの性質はグローバルであり、探索で使用するプロパティは、頂点ラベルとプロパティのペアによって一意に識別されます。エッジ・プロパティは削除および再利用されるため、更新の負荷が高くなります。エッジ・プロパティは、使用が必要な場合に使用してください。
    // Property Keys 
    // Check for previous creation of property key with 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() is optional, as it is the default
    schema.propertyKey('comment').Text().single().create()
    // Example of a multiple property that can have several values
    // Next 4 lines define two properties, then create a meta-property 'livedIn' on 'country'  
    // A meta-property is a property of a property
    // EX: '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()を使用します。プロパティ・キーを作成するには、single()またはmultiple()を指定して、単一または複数のカーディナリティを使用します。デフォルトは単一のカーディナリティです。これを指定する必要はありませんが、例に示すように明示的に記述することもできます。

    メタプロパティ、つまりプロパティのプロパティを作成するには、propertyKey()の後にproperties()を続けて使用します。メタプロパティを作成する前に、プロパティ・キーが存在している必要があります。

  7. 頂点ラベルを定義します。頂点ラベルは、作成可能な頂点のタイプを識別します。
    /// Vertex Labels
    schema.vertexLabel('author').ifNotExists().create()
    schema.vertexLabel('recipe').create()
    // Example of creating vertex label with properties
    // schema.vertexLabel('recipe').properties('name','instructions').create()
    schema.vertexLabel('ingredient').create()
    schema.vertexLabel('book').create()
    schema.vertexLabel('meal').create()
    schema.vertexLabel('reviewer').create()
    // Example of custom vertex 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とともに作成できます。
    注: DSE 6.0では、標準の自動生成IDは廃止されました。カスタムIDにはいくつかの変更が加えられ、partitionKeyおよびclusteringKeyを使用して頂点IDを指定する方法が一般的になる可能性が高くなります。

    DSE Graphでは、グラフごとに入力できる頂点ラベル数は200までです。

  8. エッジ・ラベルを定義します。エッジ・ラベルは、作成可能なエッジのタイプを識別します。
    // Edge Labels
    schema.edgeLabel('authored').ifNotExists().create()
    schema.edgeLabel('created').create()
    schema.edgeLabel('includes').create()
    schema.edgeLabel('includedIn').create()
    schema.edgeLabel('rated').properties('stars').connection('reviewer','recipe').create()

    エッジ・ラベルが以前に存在していたかどうかをチェックするには、ifNotExists()を使用します。エッジ・ラベルを作成するには、connection()で識別される隣接頂点ラベルを使用します。

  9. クエリー処理を高速化できるインデックスを定義します。ここでは、インデックスのすべての型を示します。
    // Vertex Indexes
    // Secondary
    schema.vertexLabel('author').index('byName').secondary().by('name').add()
    // Materialized	  		
    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()
    // Search
    // schema.vertexLabel('recipe').index('search').search().by('instructions').asText().add()
    // schema.vertexLabel('recipe').index('search').search().by('instructions').asString().add()
    // If more than one property key is search indexed
    // schema.vertexLabel('recipe').index('search').search().by('instructions').asText().by('category').asString().add()
    
    // Edge Index
    schema.vertexLabel('reviewer').index('ratedByStars').outE('rated').by('stars').add()
    
    // Example of property index using meta-property 'livedIn': 
    // schema().vertexLabel('author').index('byLocation').property('country').by('livedIn').add()
  10. グラフ・スキーマを作成した後、確認のためにそのスキーマを検証します。このコマンドは、フル・スクリプトの最後のコマンドとして含まれています。
     schema.describe()
    ==>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()

// RECIPE SCHEMA

// To run in Studio, copy and paste all lines to a cell and run.

// To run in Gremlin console, use the load command
// :load /tmp/RecipeSchema.groovy

    	
// Property Keys 
// Check for previous creation of property key with 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() is optional, as it is the default
schema.propertyKey('comment').Text().single().create()
// Example of a multiple property that can have several values
// Next 4 lines define two properties, then create a meta-property 'livedIn' on 'country'  
// A meta-property is a property of a property
// EX: '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()  
    		
// Vertex Labels
schema.vertexLabel('author').ifNotExists().create()
schema.vertexLabel('recipe').create()
// Example of creating vertex label with properties
// schema.vertexLabel('recipe').properties('name','instructions').create()
schema.vertexLabel('ingredient').create()
schema.vertexLabel('book').create()
schema.vertexLabel('meal').create()
schema.vertexLabel('reviewer').create()
// Example of custom vertex id:
// schema.propertyKey('city_id').Int().create()
// schema.propertyKey('sensor_id').Uuid().create()
// schema().vertexLabel('FridgeSensor').partitionKey('city_id').clusteringKey('sensor_id').create()
                
// Edge Labels
schema.edgeLabel('authored').ifNotExists().create()
schema.edgeLabel('created').create()
schema.edgeLabel('includes').create()
schema.edgeLabel('includedIn').create()
schema.edgeLabel('rated').properties('stars').connection('reviewer','recipe').create()
                
// Vertex Indexes
// Secondary
schema.vertexLabel('author').index('byName').secondary().by('name').add()
// Materialized	  		
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()
// Search
// schema.vertexLabel('recipe').index('search').search().by('instructions').asText().add()
// schema.vertexLabel('recipe').index('search').search().by('instructions').asString().add()
// If more than one property key is search indexed
// schema.vertexLabel('recipe').index('search').search().by('instructions').asText().by('category').asString().add()

// Edge Index
schema.vertexLabel('reviewer').index('ratedByStars').outE('rated').by('stars').add()

// Property index using meta-property 'livedIn': 
schema.vertexLabel('author').index('byLocation').property('country').by('livedIn').add()

// Schema description
// Use to check that the schema is built as desired
schema.describe()