メジャーを使用する

このドキュメントでは、グラフでメジャーを定義してクエリする方法について説明します。 メジャーを使用すると、結合全体で集計が正しく行われるようにできます。

概要

メジャー は、ノードテーブルまたはエッジテーブルの PROPERTIES 句内で定義される集計プロパティです。メジャーは、MEASURE キーワードと、次のいずれかのサポートされている集計関数を使用して定義されます。

  • SUM
  • AVG
  • COUNT
  • COUNT(DISTINCT)
  • MIN
  • MAX

メジャーは、定義されているノードテーブルまたはエッジテーブルの KEY を参照して集計を定義します。つまり、メジャーをクエリすると、基盤となるテーブルが重複する行を引き起こす方法で結合されている場合でも、集計が正しく行われます。

GQL クエリでメジャーによって定義されたプロパティを参照することはできません。代わりに、 グラフのフラット化されたテーブル表現を作成するために、 GRAPH_EXPAND TVF を呼び出すことでメジャーにアクセスします。この関数は、すべてのタイプのグラフを受け入れるわけではありません。有効な入力となるグラフの詳細については、入力の制限をご覧ください。

AGG 関数GRAPH_EXPAND TVF の出力に対して呼び出して、メジャーで定義した集計関数に従ってプロパティを集計できます。

メジャーを定義する

ノードテーブルまたはエッジテーブル定義の PROPERTIES 内で、サポートされている集計関数をMEASURE()キーワードで囲むことで、メジャーを定義します。

次の例では、university という名前のデータセットと、大学、学部、コースのテーブルを作成します。

CREATE SCHEMA IF NOT EXISTS university;

CREATE OR REPLACE TABLE university.College (
  college_id INT64 PRIMARY KEY NOT ENFORCED,
  college_name STRING
);

CREATE OR REPLACE TABLE university.Department (
  dept_id INT64 PRIMARY KEY NOT ENFORCED,
  dept_name STRING,
  college_id INT64,
  budget FLOAT64,
  FOREIGN KEY (college_id) REFERENCES university.College(college_id) NOT ENFORCED
);

CREATE OR REPLACE TABLE university.Course (
  course_id INT64 PRIMARY KEY NOT ENFORCED,
  course_name STRING,
  dept_id INT64,
  credits INT64,
  FOREIGN KEY (dept_id) REFERENCES university.Department(dept_id) NOT ENFORCED
);

INSERT INTO university.College (college_id, college_name)
VALUES (101, 'College of Engineering'),
      (102, 'College of Arts');

INSERT INTO university.Department (dept_id, dept_name, college_id, budget)
VALUES (1001, 'Computer Science', 101, 500000),
      (1002, 'Mechanical Engineering', 101, 400000),
      (1003, 'Fine Arts', 102, 200000),
      (1004, 'Research', 101, 50000);

INSERT INTO university.Course (course_id, course_name, dept_id, credits)
VALUES (1, 'Intro to CS', 1001, 3),
       (2, 'Data Structures', 1001, 4),
       (3, 'Thermodynamics', 1002, 3),
       (4, 'Oil Painting', 1003, 2);

次のステートメントは、Department ノードと Course ノードの一部のプロパティにメジャーを定義する SchoolGraph という名前のグラフを作成します。 メジャーによって定義されたプロパティにはエイリアスを指定する必要があります。

CREATE OR REPLACE PROPERTY GRAPH university.SchoolGraph
  NODE TABLES (
    university.College
      KEY(college_id)
      PROPERTIES(college_id, college_name),
    university.Department
      KEY(dept_id)
      PROPERTIES(dept_id, dept_name, college_id,
        budget OPTIONS(description="Department budget in USD"),
        MEASURE(SUM(budget)) AS total_budget),
    university.Course
      KEY(course_id)
      PROPERTIES(
        course_id,
        course_name,
        credits,
        dept_id,
        MEASURE(AVG(credits)) AS avg_credits,
        MEASURE(SUM(credits)) AS total_credits,
        MEASURE(COUNT(course_id)) AS course_count)
  )
  EDGE TABLES (
    university.Department AS CollegeDept
      SOURCE KEY (college_id) REFERENCES College (college_id)
      DESTINATION KEY (dept_id) REFERENCES Department (dept_id),
    university.Course AS DeptCourse
      SOURCE KEY (dept_id) REFERENCES Department (dept_id)
      DESTINATION KEY (course_id) REFERENCES Course (course_id)
  );

SchoolGraph グラフの可視化。

total_budget メジャーは MEASURE(SUM(budget)) として定義されます。このメジャーは、集計を KEYdept_id)にロックします。

重複カウントについて

テーブルを結合すると、データに一対多のリレーションシップがあるたびにデータが繰り返されます。たとえば、CourseDepartmentCollege テーブルを結合すると、複数のコースがある学部が出力で複数の行に表示されます。

SELECT
  college_name,
  dept_name,
  course_name,
  budget
FROM university.Course
LEFT JOIN university.Department
  ON Course.dept_id = Department.dept_id
LEFT JOIN university.College
  ON Department.college_id = College.college_id;

/*------------------------+------------------------+-----------------+----------+
 | college_name           | dept_name              | course_name     | budget   |
 +------------------------+------------------------+-----------------+----------+
 | College of Engineering | Computer Science       | Intro to CS     | 500000.0 |
 | College of Engineering | Computer Science       | Data Structures | 500000.0 |
 | College of Engineering | Mechanical Engineering | Thermodynamics  | 400000.0 |
 | College of Arts        | Fine Arts              | Oil Painting    | 200000.0 |
 +------------------------+------------------------+-----------------+----------*/

SUM(budget) を使用して大学ごとの合計予算を計算しようとすると、コンピュータ サイエンス学部の予算が 2 回カウントされます。この問題を回避するには、Department テーブルを直接クエリしますが、このアプローチは、結合されたデータに寄与する異なるテーブルから複数の集計を計算する場合に機能しません。次のセクションでは、メジャーがこの問題を解決する方法について説明します。

メジャーを使用してグラフをクエリする

GQL を使用してメジャーを含むグラフをクエリできますが、クエリでメジャーによって定義されたプロパティを直接参照することはできません。たとえば、次のクエリはメジャー プロパティが定義されているノードを参照しますが、メジャー フィールドを使用または返しません。

GRAPH university.SchoolGraph
MATCH (c:College)-[]-(d:Department)-[]->(course:Course)
RETURN c.college_name, d.dept_name, course.course_name;

/*------------------------+------------------------+-----------------+
 | college_name           | dept_name              | course_name     |
 +------------------------+------------------------+-----------------+
 | College of Engineering | Computer Science       | Intro to CS     |
 | College of Engineering | Computer Science       | Data Structures |
 | College of Engineering | Mechanical Engineering | Thermodynamics  |
 | College of Arts        | Fine Arts              | Oil Painting    |
 +------------------------+------------------------+-----------------*/

メジャーを使用する

メジャーを使用するには、 GRAPH_EXPAND テーブル値関数(TVF) を使用して、グラフを 1 つのフラット化されたテーブルとしてクエリします。出力テーブルの列は、各ノードテーブルとエッジテーブルのグラフで定義されたプロパティから派生します。名前の競合を防ぐため、列にはノードテーブルまたはエッジテーブルのラベルとプロパティ名を連結した名前が付けられます(例: Course_course_nameDepartment_total_budget)。次のクエリは、GRAPH_EXPAND TVF からの出力例を示しています。

SELECT
  College_college_name,
  Department_dept_name,
  Department_budget,
  Course_course_name
FROM
  GRAPH_EXPAND("university.SchoolGraph");

/*------------------------+------------------------+-------------------+--------------------+
 | College_college_name   | Department_dept_name   | Department_budget | Course_course_name |
 +------------------------+------------------------+-------------------+--------------------+
 | College of Engineering | Computer Science       | 500000.0          | Intro to CS        |
 | College of Engineering | Computer Science       | 500000.0          | Data Structures    |
 | College of Engineering | Mechanical Engineering | 400000.0          | Thermodynamics     |
 | College of Arts        | Fine Arts              | 200000.0          | Oil Painting       |
 +------------------------+------------------------+-------------------+--------------------+

GRAPH_EXPAND 関数は、一連の LEFT JOIN オペレーションをノードテーブルとエッジテーブルに適用して、フラット化されたテーブルを生成します。有効な入力グラフには、ルートノードテーブルが 1 つだけ必要です。これは、KEY 値が他のテーブルに表示されないテーブルです。一連の結合を介してルートノード テーブルから到達できないデータは、出力に表示されません。前の例では、Course テーブルがルートノード テーブルです。コースがないため、Research 学部は出力から除外されます。

メジャーによって定義されたプロパティの列を直接選択することはできません。 代わりに、 AGG()関数でラップする必要があります。 この関数により、メジャーで定義された集計がキーごとに 1 回だけ実行されます。

次のクエリは、各大学の合計予算とコースの合計数を同時に計算します。

SELECT
  College_college_name,
  AGG(Department_total_budget) AS college_budget,
  AGG(Course_course_count) AS total_courses
FROM
  GRAPH_EXPAND("university.SchoolGraph")
GROUP BY
  College_college_name;

/*------------------------+----------------+---------------+
 | College_college_name   | college_budget | total_courses |
 +------------------------+----------------+---------------+
 | College of Engineering | 900000.0       | 3             |
 | College of Arts        | 200000.0       | 1             |
 +------------------------+----------------+---------------*/

GRAPH_EXPAND スキーマを表示する

GRAPH_EXPAND 関数を呼び出さずに、この関数から返されるテーブルのスキーマを表示するには、BQ.SHOW_GRAPH_EXPAND_SCHEMA システム プロシージャを使用します。

DECLARE schema STRING DEFAULT '';
CALL BQ.SHOW_GRAPH_EXPAND_SCHEMA('university.SchoolGraph', schema);
SELECT schema;

このプロシージャは、各列の名前、型、モードを schema 変数に入力します。また、列で参照されるプロパティがメジャーであるかどうかを示し、定義した説明やシノニムを一覧表示します。

次のステップ

  • プロパティ グラフを作成してクエリする方法を学習する
  • グラフ スキーマについて学習する。