すべてのプロダクト
Search
ドキュメントセンター

AnalyticDB:グラフ分析エンジンの作成と使用

最終更新日:May 24, 2025

このトピックでは、AnalyticDB for PostgreSQL でグラフ分析エンジンを作成および使用する方法について説明します。

Cypher とは

Cypher は、openCypher プロジェクトによって提供されるオープンソースの宣言型クエリ言語です。 SQL に似ていますが、グラフデータ構造向けに最適化されています。直感的で自然言語のような構文を使用して、Cypher はノード間の関係を明確に表現し、グラフマッチングパターンを定義できるため、効率的かつ容易なグラフデータクエリが可能になります。例:

MATCH (n:nodes)-[r:ARE_CONNECTED_TO]->(o:otherNodes)
RETURN n,r,o

上記の Cypher 文は、パターンマッチングを使用して、グラフ内で特定の条件を満たすすべてのノードとリレーションシップをクエリします。この文では、(n:nodes) は、nodes ラベルを持つ n という名前のノードを表します。[r:ARE_CONNECTED_TO] は、ARE_CONNECTED_TO ラベルを持つ r という名前のリレーションシップを表します。(o:otherNodes) は、otherNodes ラベルを持つ o という名前のターゲットノードを表します。この文は、このパターンに一致するすべてのソースノード、ターゲットノード、およびそれらのリレーションシップを返します。

構文

ノード構文

Cypher は、一対の括弧 () を使用してノードを表します。以下は、一般的なノード表現とその意味です。

  • ():ラベルのない匿名ノード。任意のノードと一致します。

  • (node)node 変数を持つノード。クエリ内のノードを参照するために使用されます。

  • (:City)City ラベルを持つノード。ラベルは、リレーショナルデータベースのテーブル名または分類識別子に似ており、特定の種類のノードをフィルタリングするために使用できます。

  • (city:City)city 変数と City ラベルを持つノード。クエリ内のノードを参照し、ノードタイプを指定するために使用されます。

  • (city:City {name: 'Hangzhou'}):キーと値の形式で {name: 'Hangzhou'} ラベルを持つノード。追加の特性を提供するために使用されます。これは、リレーショナルデータベースの WHERE 句と同様に、特定のラベル値を持つノードを正確に照合するのに役立ちます。

  • (city:City {name: 'Hangzhou', province: 'Zhejiang'}):複数のラベルを持つノード。複雑な条件フィルタリングを実装するために使用されます。

リレーションシップ構文

Cypher は、一対のハイフン(--)を使用してリレーションシップを表します。方向付きリレーションシップは、--> など、一端に矢印で示されます。角括弧([])を使用して、変数、タイプ、ラベルなど、詳細なリレーションシップを指定できます。以下は、一般的なリレーションシップ表現とその意味です。

  • --:特定のタイプのない匿名の無方向リレーションシップ。

  • -->:特定のタイプのない匿名の方向付きリレーションシップ。

  • -[role]->role 変数を持つリレーションシップ。クエリ内のリレーションシップを参照するために使用されます。

  • -[:ACTED_IN]->:ノードラベルと同様の ACTED_IN リレーションシップ。

  • -[role:ACTED_IN]->role 変数を持つ ACTED_IN リレーションシップ。

  • -[role:ACTED_IN {roles: ['Neo']}]->{roles: ['Neo']} ラベルを持つリレーションシップ。追加の特性を提供するために使用されます。

リレーションシップの角括弧の構文とセマンティクスは、ノードの括弧の構文に似ています。

  • 変数:role などのリレーションシップ変数は、ノード変数に似ており、クエリ内の参照に使用されます。

  • タイプ:ACTED_IN などのリレーションシップタイプは、ノードラベルに似ており、特定のリレーションシップを分類およびフィルタリングするために使用されます。

  • ラベル:{roles: ['Neo']} などのリレーションシップラベルは、ノードラベルと機能的に同等であり、キーと値の形式で詳細なリレーションシップを指定するために使用されます。

パターン構文

ノードとリレーションシップの構文を統合して、豊富なセマンティック情報を伝えるパターンを構築できます。パターンの式の例:

(city_from:City {province: 'Zhejiang'})-[:NEXT_TO]-(city_next:City {province: 'Jiangsu'})

式の意味:

  • (city_from:City {province: 'Zhejiang'})provinceZhejiang である City ラベルを持つノード。

  • (city_next:City {province: 'Jiangsu'})provinceJiangsu である City ラベルを持つノード。

  • -[:NEXT_TO]-:2 つの都市間の地理的隣接関係を指定するために使用される NEXT_TO 無方向エッジ。

このパターンの式は、浙江省と江蘇省の間の隣接都市関係と一致します。パラメーターの説明:

  • city_fromcity_next は、それぞれ浙江省と江蘇省の都市ノードを表します。

  • [:NEXT_TO] は、2 つの都市間の地理的隣接関係を表します。

サポートされているバージョン

AnalyticDB for PostgreSQL V7.0 インスタンス V7.2.1.0 以降。

説明

AnalyticDB for PostgreSQL コンソールのインスタンスの マイナーバージョン注:インスタンスのマイナーバージョンを更新する ページで を表示できます。インスタンスが必要なバージョンを満たしていない場合は、 してください。

前提条件

  • AnalyticDB for PostgreSQL インスタンスに 年齢拡張機能がインストールされている こと。

  • クエリを簡素化するために、search_path パラメーターで指定された検索パスに ag_catalog スキーマが追加されていること。次のいずれかの方法を使用できます。

    • セッションレベルの構成。

      SET search_path TO public, ag_catalog;
    • データベースレベルの永続的な構成。

      ALTER DATABASE <database_name> SET search_path TO public, ag_catalog;
  • (オプション) 初期アカウント または RDS_SUPERUSER 権限を持つ特権アカウント を使用して、他のユーザーに ag_catalog スキーマへのアクセス権を付与します。

    GRANT USAGE ON SCHEMA ag_catalog TO <username>;

グラフ分析エンジンの作成と使用

グラフの作成

構文

create_graph() 関数を呼び出してグラフを作成します。

SELECT create_graph('<graph_name>');

パラメーター

graph_name:グラフの名前。

SELECT create_graph('relation');

データの書き込み

構文

ag_catalog スキーマで cypher() 関数を呼び出して、ノードとリレーションシップを作成する式を記述します。

SELECT * FROM cypher('<graph_name>', $$
  /* Cypher 式を記述します。*/
  $$) AS (result_a agtype, result_b agtype);

次のグラフには、3 つの Person ノード (Zhang San、Li Si、Wang Wu) と 2 つの Company ノード (Company A と Company C) が含まれています。Person は EMPLOYED エッジを使用して Company に接続され、Person は FRIENDS エッジと TEACHER エッジを使用して互いに接続されています。

relation グラフにデータを書き込みます。

SELECT * FROM cypher('relation', $$
  CREATE (ZhangSan:Person {name: 'Zhang San'})
  CREATE (LiSi:Person {name: 'Li Si'})
  CREATE (WangWu:Person {name: 'Wang Wu'})
  CREATE (company_a:Company {name: 'Company A'})
  CREATE (company_c:Company {name: 'Company C'})
  CREATE (ZhangSan)-[:EMPLOYED]->(company_a)
  CREATE (LiSi)-[:EMPLOYED]->(company_c)
  CREATE (WangWu)-[:EMPLOYED]->(company_a)
  CREATE (ZhangSan)-[:FRIENDS]->(LiSi)
  CREATE (WangWu)-[:TEACHER]->(ZhangSan)
$$) AS (result_a agtype)

データのクエリ

構文

MATCH キーワードと RETURN キーワードを使用してデータをクエリします。MATCH は、ノード、リレーションシップ、およびそれらのプロパティを含む、一致させるグラフパターンを定義します。RETURN は、クエリ結果で必要な戻りデータを指定します。

SELECT * FROM cypher('<graph_name>', $$
  MATCH <patterns>
  WHERE <expression> --optional
  RETURN <variables>
$$) AS (result_a agtype);

すべてのデータのクエリ

  • Person ラベルを持つすべてのノードをクエリします。

    SELECT * FROM cypher('relation', $$
      MATCH (m:Person)
      RETURN m
    $$) AS (result_a agtype)

    結果の例:

                                            result_a                                         
    -----------------------------------------------------------------------------------------
     {"id": 844424930131969, "label": "Person", "properties": {"name": "Zhang San"}}::vertex
     {"id": 844424930131970, "label": "Person", "properties": {"name": "Li Si"}}::vertex
     {"id": 844424930131971, "label": "Person", "properties": {"name": "Wang Wu"}}::vertex
    (3 rows)
  • EMPLOYED ラベルを持つすべてのエッジをクエリします。

    SELECT * FROM cypher('relation', $$
      MATCH (:Person)-[r:EMPLOYED]->(:Company)
      RETURN r
    $$) AS (result_a agtype);

    結果の例:

                                                                result_a                                                            
    --------------------------------------------------------------------------------------------------------------------------------
     {"id": 1407374883553281, "label": "EMPLOYED", "end_id": 1125899906842625, "start_id": 844424930131969, "properties": {}}::edge
     {"id": 1407374883553282, "label": "EMPLOYED", "end_id": 1125899906842626, "start_id": 844424930131970, "properties": {}}::edge
     {"id": 1407374883553283, "label": "EMPLOYED", "end_id": 1125899906842625, "start_id": 844424930131971, "properties": {}}::edge
    (3 rows)

部分データ (フィルタリングされたデータ) のクエリ

グラフでパターンマッチングを実行し、特定のデータを返すには、WHERE 句を使用して、条件に基づいて結果をフィルタリングします。

  • Company A のすべての従業員をクエリします。

    SELECT * FROM cypher('relation', $$
      MATCH (p:Person)-[:EMPLOYED]->(a:Company)
      WHERE a.name='Company A'
      RETURN p
    $$) AS (result_a agtype);

    結果の例:

                                            result_a                                         
    -----------------------------------------------------------------------------------------
     {"id": 844424930131969, "label": "Person", "properties": {"name": "Zhang San"}}::vertex
     {"id": 844424930131971, "label": "Person", "properties": {"name": "Wang Wu"}}::vertex
    (2 rows)
  • Wang Wu の生徒をクエリします。

    SELECT * FROM cypher('relation', $$
      MATCH (p1:Person)-[:TEACHER]->(p2:Person)
      WHERE p1.name='Wang Wu'
      RETURN p2
    $$) AS (result_a agtype)

    結果の例:

                                            result_a                                         
    -----------------------------------------------------------------------------------------
     {"id": 844424930131969, "label": "Person", "properties": {"name": "Zhang San"}}::vertex
    (1 row)

データの更新 (ノードまたはエッジ)

グラフ内の既存のデータ (ノードやリレーションシップなど) を変更するには、ターゲットオブジェクトを照合し、SET キーワードを使用してデータを追加または更新します。

構文

SELECT * FROM cypher('<graph_name>', $$
  MATCH <patterns>
  SET <property>
  RETURN <variable>
$$) AS (result_a agtype)

  • Zhang San の名前を Zhang 3 に変更します。

    SELECT * FROM cypher('relation', $$
      MATCH (p:Person {name:'Zhang San'})
      SET p.name='Zhang 3'
      RETURN p
    $$) AS (result_a agtype);

    結果の例:

                                           result_a                                        
    ---------------------------------------------------------------------------------------
     {"id": 844424930131969, "label": "Person", "properties": {"name": "Zhang 3"}}::vertex
    (1 row)
  • 値が male の gender ラベルを Zhang San に追加します。

    SELECT * FROM cypher('relation', $$
      MATCH (p:Person {name: 'Zhang 3'})
      SET p.gender = 'male'
      RETURN p
    $$) AS (result_a agtype);

    結果の例:

                                                    result_a                                                 
    ---------------------------------------------------------------------------------------------------------
     {"id": 844424930131969, "label": "Person", "properties": {"name": "Zhang 3", "gender": "male"}}::vertex
    (1 row)

データの削除

ラベルの削除

ノードまたはエッジラベルが不要になった場合は、REMOVE キーワードを使用してラベルを削除できます。

構文

SELECT * FROM cypher('<graph_name>', $$
  MATCH <patterns>
  REMOVE <property>
$$) AS (result_a agtype);

Zhang San から gender ラベルを削除します。

SELECT * FROM cypher('relation', $$
  MATCH (p:Person {name: 'Zhang 3'})
  REMOVE p.gender
  RETURN p
$$) AS (result_a agtype);

ノードの削除

DELETE キーワードを使用して、ノードまたはエッジを削除します。

構文

SELECT * FROM cypher('<graph_name>', $$
  MATCH <patterns>
  DELETE <variable>
$$) AS (result_a agtype);

Zhao Liu という名前のノードを作成し、そのノードを削除します。

-- Zhao Liu という名前のノードを作成します。
SELECT * FROM cypher('relation', $$
  CREATE (:Person {name: 'Zhao Liu'})
$$) AS (result_a agtype)

-- ノードを削除します。
SELECT * FROM cypher('relation', $$
  MATCH(p:Person {name: 'Zhao Liu'})
  DELETE p
$$) AS (result_a agtype)
説明

エッジを持つノードを直接削除することはできません。代わりに、DETACH DELETE 文を実行して、ノードとそのエッジを削除 します。

エッジの削除

Zhao Liu という名前のノードと、Zhao Liu と Company C の間の EMPLOYED エッジを作成します。次に、WHERE 句で Person 名と Company 名を指定して、エッジを削除します。

-- Zhao Liu という名前のノードと、Zhao Liu と Company C の間の EMPLOYED エッジを作成します。
SELECT * FROM cypher('relation', $$
  CREATE (ZhaoLiu:Person {name: 'Zhao Liu'})
  CREATE (ZhaoLiu)-[:EMPLOYED]->(:Company {name: 'Company C'})
$$) AS (result_a agtype);

-- エッジを削除します。
SELECT * FROM cypher('relation', $$
  MATCH (p:Person)-[r:EMPLOYED]->(c:Company)
  WHERE p.name='Zhao Liu' AND c.name='Company C'
  DELETE r
$$) AS (result_a agtype);

ノードとそのエッジの削除

エッジを持つノードを直接削除することはできません。代わりに、DETACH DELETE 文を実行して、ノードとそのエッジを削除します。

構文

SELECT * FROM cypher('<graph_name>', $$
  MATCH <patterns>
  DETACH DELETE <variable>
$$) AS (result_a agtype);

Zhao Liu という名前のノードと、Zhao Liu と Company C の間の EMPLOYED エッジを作成します。次に、エッジと Zhao Liu ノードを削除します。

-- Zhao Liu という名前のノードと、Zhao Liu と Company C の間の EMPLOYED エッジを作成します。
SELECT * FROM cypher('relation', $$
  CREATE (ZhaoLiu:Person {name: 'Zhao Liu'})
  CREATE (ZhaoLiu)-[:EMPLOYED]->(:Company {name: 'Company C'})
$$) AS (result_a agtype);

-- ノードとそのエッジを削除します。
SELECT * FROM cypher('relation', $$
  MATCH (p:Person {name: 'Zhao Liu'})
  DETACH DELETE p
$$) AS (result_a agtype);