Studioを使用したグラフ・スキーマの作成

DataStax StudioおよびGroovyを使用したグラフ・データベース・スキーマの作成。

グラフ・データベースのデータ・モデルの作成は、スキーマを作成するための重要な最初のステップです。データ・モデルが指定され、グラフが作成されたら、グラフ・データベース作成の次のステップは、頂点とエッジおよびそのプロパティのスキーマを定義することです。DataStax Studioのセルにスクリプトを入力するには、Gremlin-Groovyを使用します。

手順

  1. 任意。以前に作成したグラフを再利用する場合は、グラフ・スキーマおよびデータを削除します
  2. サイズの大きなスクリプトを実行する場合は、timeoutの値を「max」に設定します。この設定を使用すると、スクリプトの処理が完了することが保証されます。このステップをStudioで行うことはできません。
    gremlin> :remote config timeout max
  3. 下記の「例」に記載するRecipeスキーマをコピーして、DataStax Studioの単一セルにペーストします。スクリプト全体が入力されたら、セルを実行します。コマンドがGremlin Serverにサブミットされます。
    注:各コマンドは単一セッション内でサブミットされるため、複数のセルにわたっていると、前の行で設定されている変数がGremlin Serverによって認識されません。Recipeスキーマ内の行が複数のセルに分かれて入力されている場合は、エッジ作成コマンドでエラーが発生します。
  4. 以下のステップは、複数のセクションに分割されたスクリプト全体の詳細を示しています。
  5. 頂点とエッジのプロパティを定義します。プロパティのデータ型がキー名に加えて指定されます。この例で作成されるプロパティは、テキスト、整数、タイムスタンプのいずれかです。その他のデータ型も使用できます。プロパティは、グラフの選択的サブセットを取得し、格納された値を取得するために使用されます。プロパティの性質はグローバルであり、探索で使用するプロパティは、頂点ラベルとプロパティのペアによって一意に識別されます。エッジ・プロパティを更新することは不経済です。なぜならば、エッジ・プロパティを更新するためにエッジ全体とそのすべてのプロパティを削除し、再作成しなければならないからです。エッジ・プロパティは、それを使用する正当な理由がある場合にしか使用しないでください。
    // 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()
    schema.propertyKey('comment').Text().single().create() // single() is optional - default
    // Example of multiple property
    // schema.propertyKey('nickname').Text().multiple().create();
    // Example meta-property added to property: 
    // schema.propertyKey('livedIn').Text().create()
    // schema.propertyKey('country').Text().multiple().properties('livedIn').create()

    プロパティ・キーが以前に存在していたかどうかをチェックするには、ifNotExists()を使用します。プロパティ・キーを作成するには、single()またはmultiple()を指定して、単一または複数のカーディナリティを使用します。デフォルトは単一のカーディナリティです。これを指定する必要はありませんが、例に示すように明示的に記述することもできます。

    メタプロパティ、つまりプロパティのプロパティを作成するには、propertyKey()の後にproperties()を続けて使用します。メタプロパティを作成する前に、プロパティ・キーが存在している必要があります。メタプロパティをネストすることはできません。つまり、メタプロパティがメタプロパティを持つことはできません。この例では、countryはメタプロパティlivedInを持つプロパティです。このプロパティとメタプロパティは、authorがその生涯のさまざまな時期に居住したことのある国を表すために使用されます。
    { "name":"Julia Child", "gender":"F", [ {"country": "United States", "livedIn": "1929-1949" }, {"country": "France", "livedIn": "1949-1952" } ], "authored":[{ "book":{ "label":"book", "bookTitle":"Art of French Cooking Volume One", "publishDate":1968 }, "book":{ "label":"book", "bookTitle":"The French Chef Cookbook", "publishDate":1968, "ISBN": "0-394-40135-2" } }], "created": [{ "type" : "recipe", "recipeTitle" : "BeefBourguignon", "instructions" : "Braise the beef.", "createDate":1967 }, { "type" : "recipe", "recipeTitle" : "Salade Nicoise", "instructions" : "Break the lettuce into pieces.", "createDate": 1970 } ] }
  6. 頂点ラベルを定義します。頂点ラベルは、作成可能な頂点のタイプを識別します。
    // 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までです。

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

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

  8. クエリー処理を高速化できるインデックスを定義します。ここでは、インデックスのすべての型を示します。 グラフ・データのインデックス作成 には、詳細情報が記載されています。
    // 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()

    これらのインデックスは、食品の例のスキーマでデータの読み込みを効率化するために追加されます。

    注: create()add()の違いはわずかですが、重要です。実体(頂点ラベルまたはエッジ・ラベル)が作成され、すでに存在している場合に、インデックスまたはプロパティ・キーがその実体に関連付けられているときは、add()コマンドが使用されます。たとえば、頂点ラベルとプロパティ・キーを作成してから、プロパティ・キーが頂点ラベルに追加される場合があります。
  9. グラフ・スキーマを作成した後、確認のためにそのスキーマを検証します。この図は出力の一部を示しています。
    schema.describe()

// RECIPE SCHEMA

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

// To run in Gremlin console, use the next two lines:
// script = new File('/tmp/RecipeSchema.groovy').text; []
// :> @script
    	
// 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()
schema.propertyKey('comment').Text().single().create() // single() is optional - default
// Example of multiple property
// schema.propertyKey('nickname').Text().multiple().create();
// Example meta-property added to property: 
// 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()

// Example of 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()