アキュムレータのチュートリアル

はじめに

GSQLはチューリング完全なグラフデータべ―スのクエリ言語です。他のグラフクエリ言語に比べてアキュムレータをサポートしていることが最大の利点で、グローバルと頂点に適用できるローカルの2種類があります。

GQSLは、従来の パターンマッチ の構文を提供するばかりでなく、実行時に利用できる強力な頂点属性 (別名 ローカルアキュムレータ) とグローバルの状態変数 (別名 グローバルアキュムレータ) をサポートしています。パターンマッチの構文そのものは容易に習得できる内容です。

この短いチュートリアルは、アキュムレータの使い方を短時間で習得できるように作成したものです。本文を読めば、誰でもアキュムレータの基本を熟知して記憶でき、この便利なGQSLの機能を使って実世界のグラフ問題を解決できるようになるでしょう。

アキュムレータとは

Figure 1. The left box is a GSQL query with different accumulators being accumulated to. The right box shows the accumulator variables' final results.

アキュムレータはGSQLの状態変数です。状態は、クエリのライフサイクルの間に変化します。初期値があり、ユーザーは、それにビルトインの演算子 "=" を使って、新しい値を積算していくことができます。アキュムレータ変数には必ずタイプが定義されており、宣言されているアキュムレータのタイプによって "=" の演算の解釈に使う意味が変わります。

図1の左側には、第3行から8行まで、6種類の異なるアキュムレータ変数が宣言されています。それぞれ固有のタイプ (接頭文字 @@) が付加されています。次にその意味と用途を説明します。

  • SumAccum<INT> は、内部の状態変数にINT値を追加し続けるアキュムレータです。10行目と11行目にあるように、1と2をアキュムレータで追加しているので、(右側のボックスの3行目にあるように) 結果が3になっています。

  • MinAccum<INT> は、遭遇したINTの最小値を維持します。14行目と15行目にあるように、MinAccum アキュムレータに1と2を入れたので、結果は (右側のボックスの6行目にあるように) 1になります。

  • MaxAccum<INT> はMinAccumの反対で、遭遇したINTの最大値を維持します。18行目と19行目にあるように、1と2を送信すると、(右側のボックスの9行目にあるように) 結果が2になります。

  • OrAccum は、内部のブール値の状態変数と追加される新しいブール値変数をOR処理にて更新します。初期のデフォルト値はFALSEです。22行目と23行目に、TRUEとFALSEが送信されていて、結果は (右側のボックスの12行目にあるように) TRUEになります。

  • AndAccum は、OrAccumの反対で、ORを使うかわりにANDを使って処理します。26行目と27行目にTRUEとFALSEが積算されていて、結果がFALSEになっています (右側のボックスの15行目)。

  • ListAccum<INT> は、内部の変数のリストに新しい整数を追加します。30行目から32行目に、1と2と、[3,4] がアキュムレータに追加されていて、結果が [1,2,3,4] になっています (右側のボックスの19~22行目)。

グローバルと頂点に附属したアキュムレータの違い

ここまでで、アキュムレータがGSQL言語では特別のタイプ変数であることを説明したので、次にグローバルとローカルの違いについて説明します。

グローバルのアキュムレータは、クエリ全体で有効です。クエリのあらゆる場所で、命令文によって値を更新することができます。一方、ローカルのアキュムレータは、各頂点のものです。親である頂点がアクセス可能な場合にのみ、更新できます。記述には、特別の接頭文字を識別子に付加して区別します。

  • @@ は、グローバルアキュムレータ変数の宣言に使う接頭文字です。常にスタンドアローンで使用します。例: **`@@cnt +=1`

  • @ は、ローカルアキュムレータ変数の宣言に使う接頭文字です。クエリブロック内で、必ず頂点のエイリアスとともに使います。例: v.@cnt += 1 ここで v は、SELECT-FROM-WHERE クエリブロックのFROM節で指定されている頂点のエイリアスです。

Figure 2. A social graph with 7 person vertices and 7 friendship edges connecting them.

図2にあるようなおもちゃに関連した人間関係を表すグラフには、人の頂点タイプと、人と人を結ぶ友達のエッジタイプがあります。このシナリオで、次のようなクエリを作成してみます。クエリは、人から始めて、入力した人から隣の人達へと1ホップ移動します。ここでは、@@global_edge_cnt アキュムレータを使って、横断していくエッジの総数を積算します。また、@vertex_cnt を使って、入力した人の友達の頂点1つひとつに整数1を書き込みます。

6PVg2z 7N7SqnLUeZOP2mdh52KQqB GCZC x5A6edcAagOWqBKWRPixykP wS tnAAqPYBWZbEBQOTHqV1GghvlsObYEW5tLkZ Nn0lIc0EsAk8 RZRP  vZQnsNn2Wy j4sB e4
Figure 3. The top box shows a query that given a person

図2にあるように、Danさんには直接つながっている友達が4人います。その4人、Tom、Kevin、Jenny、Nancyの各々にローカルのアキュムレータ @vertex_cnt があります。 そして、各エッジに1が積算されているので、@@global_edge_cnt の値は4です。

ACCUM と POST-ACCUMの違い

ACCUMとPOST-ACCUMの節は、順番に処理され、SELECT-FROM-WHEREクエリブロック内で、ACCUMが先に実行され、次にPOST-ACCUM節が実行されます。

  • ACCUM は、FROM節のパターンから一致したエッジ (またはパス) につき、命令文を1回実行します。さらに、一致したもの全てに対する命令文の実行は、並列で行われます。

  • POST-ACCUM は、関連の頂点に対して命令文を1回ずつ実行します。なお、POST-ACCUM節内の命令文の対象は、ソース頂点でもターゲット頂点でも有効ですが、両方を対象にすることはできません。また、ACCUM節で計算されて集合されたアキュムレータの結果を対象にすることができます。

結論

以上がアキュムレータのメカニズムの説明です。タイプや、グローバルとローカルという2つの異なるスコープについて、また、ACCUMとPOST-ACCUM節の使い方について解説しまし。この基本をマスターすれば、あとは練習です。 LDBC のスキーマに基づいたクエリを46個用意しているのでお使いください。この46個のクエリは次の3つのグループに分けてあります。

環境の設定はGSQL 102 を参照して実行してください。GSQLを使ったグラフジャーニーの経験について、フィードバックや質問は GSQL community forumにお寄せください。不明な点などについて回答します。コミュニティのメンバーと開発エンジニアが皆さんの投稿をお待ちしています。