Quick Start

更新时间:
复制 MD 格式

A Graph Database stores graph data and is ideal for handling complex relationships such as social networks and knowledge graphs. Use graph query languages such as Cypher or Gremlin to work with this data. PolarDB supports OpenCypher syntax and provides features including creating, querying, updating, and deleting graph data, pattern matching, filtering, MERGE to avoid duplicates, and visualization tools—simplifying graph data management and application development.

Applicable scope

The following versions of PolarDB for PostgreSQL are supported:

  • PostgreSQL 16 (minor engine version 2.0.16.8.3.0 or later)

  • PostgreSQL 15 (minor engine version 2.0.15.12.4.0 or later)

  • PostgreSQL 14 (minor engine version 2.0.14.12.24.0 or later)

Note

View your minor engine version in the console, or run the SHOW polardb_version; statement. If your version does not meet the requirement, upgrade the minor engine version.

Terms

  • Graph: A graph is a data structure made up of nodes and edges. For example, a social network is a typical graph where each person is a node and their relationships such as friends, family, or colleagues are edges.

    image

  • Node: A node is a basic element in a graph database that represents an entity. Nodes can have properties that store information about the entity. In a social network, nodes might represent users, companies, or organizations.

  • Edge: An edge connects nodes and represents a relationship. Edges can have attributes such as weight or direction to indicate the strength or orientation of the relationship. In a social network, edges might represent follows, friendships, or fan relationships.

  • Label: A label is a category or attribute used to classify nodes or edges. Labels help give semantic meaning to your data, making queries and analysis easier. In a social network, node labels might include Person or Company, while edge labels might include Knows or WorkIn.

  • Property graph: A graph is called a property graph if its nodes contain properties (details about the entity) or its edges contain properties (details about the relationship). The following example shows a colleague relationship as a property graph, with relevant attributes on both nodes and edges:

    image

  • Graph Database: A specialized database that uses graphs to store data—nodes represent entities and edges represent relationships. It excels at handling complex relational data such as social networks, trust networks, and knowledge graphs.

    Graph databases use graph query languages such as Cypher or Gremlin to query data. PolarDB supports OpenCypher syntax. OpenCypher is an open-source subset of Cypher, and most of its features are equivalent to Cypher.

Schema

Properties

In Cypher, use curly braces {} to define properties. Properties consist of key-value pairs, similar to JSON. Keys are strings, and values can be strings, numbers, or arrays. For example, {name: 'Reeves'} means the name is Reeves.

Nodes

In Cypher, use parentheses () to represent nodes. Here are some examples:

()
(matrix)
(:Movie)
(matrix:Movie)
(matrix:Movie {title: 'The Matrix'})
(matrix:Movie {title: 'The Matrix', released: 1997})

Where:

  • The simplest form () represents an anonymous, uncharacterized node.

  • To reference the node elsewhere in the same statement, add a variable—for example, (matrix). Variables apply only within a single statement and may have different or no meaning in other statements.

  • :Movie declares the node’s label, restricting the pattern to match only nodes with that label.

  • {title: 'The Matrix'} defines node properties, which can store information or constrain the pattern.

Edges

In Cypher, use two dashes -- for an undirected edge, or add an arrow—<-- or -->—for a directed edge. Use bracket expressions [...] to add details such as variables, properties, or type information. Examples:

--
-->
-[role]->
-[:ACTED_IN]->
-[role:ACTED_IN]->
-[role:ACTED_IN {roles: ['Neo']}]->

Where:

  • -- is an anonymous undirected edge.

  • --> is an anonymous directed edge.

  • You can define a variable (for example, role) to use elsewhere in the statement.

  • Relationship labels (for example, :ACTED_IN) work like node labels.

  • Properties (for example, roles: ['Neo']) are defined the same way as node properties.

Examples

The following example shows how to use graph features in PolarDB. The sample data is a simple movie database containing actors and films.

Create the extension

Use a privileged account to run the following statement. To create a privileged account, see Create a database account .

Note

The age extension does not currently support manual creation. To use this feature, submit a ticket to contact us so we can create the extension for you.

CREATE EXTENSION age;

Configure the database

For each connection, add ag_catalog to the search_path to simplify queries, and load the extension using the get_cypher_keywords function:

Note

Compatibility issues may occur when you use Data Management (DMS) to configure the search_path. In such cases, you can use PolarDB-Tools to execute related statements.

SET search_path = ag_catalog, "$user", public;
SELECT * FROM get_cypher_keywords() limit 0;

We strongly recommend that a privileged account configure database parameters to load the extension permanently. This avoids repeating the above steps on every connection and simplifies usage.

ALTER DATABASE <dbname> SET search_path = "$user", public, ag_catalog;
ALTER DATABASE <dbname> SET session_preload_libraries TO 'age';

Grant AGE access to regular users

Grant USAGE permission on the ag_catalog schema to regular users.

GRANT USAGE ON SCHEMA ag_catalog TO <username>;

If the regular user is an RW user, also grant the CREATE permission to allow table creation.

GRANT CREATE ON DATABASE <dbname> TO <username>;

Query structure

Cypher queries in PolarDB are built by calling the cypher function in ag_catalog, which returns a SETOF records. Here is a typical query:

SELECT * FROM cypher('graph_name', $$
/* Write your Cypher query here */
$$) AS (result1 agtype, result2 agtype);

Here, graph_name is the name of the graph, and replace the /*  */ block with your actual Cypher query.

Create a graph

Before using a graph, create it first. Use the create_graph function in the ag_catalog namespace.

Syntax:

SELECT create_graph('<graph_name>');

Example:

Create a graph named moviedb.

SELECT create_graph('moviedb');

Insert data

Run the following SQL statement to insert sample data into the moviedb graph:

SELECT * FROM cypher('moviedb', $$
  CREATE (matrix:Movie {title: 'The Matrix', released: 1997})
  CREATE (cloudAtlas:Movie {title: 'Cloud Atlas', released: 2012})
  CREATE (forrestGump:Movie {title: 'Forrest Gump', released: 1994})
  CREATE (keanu:Person {name: 'Keanu Reeves', born: 1964})
  CREATE (robert:Person {name: 'Robert Zemeckis', born: 1951})
  CREATE (tom:Person {name: 'Tom Hanks', born: 1956})
  CREATE (tom)-[:ACTED_IN {roles: ['Forrest']}]->(forrestGump)
  CREATE (tom)-[:ACTED_IN {roles: ['Zachry']}]->(cloudAtlas)
  CREATE (robert)-[:DIRECTED]->(forrestGump)
$$) AS (result1 agtype);

This creates six nodes—three labeled Movie and three labeled Person—and three edges: two labeled ACTED_IN and one labeled DIRECTED. The relationship diagram is shown below:

image

Query data

Data query

In Cypher, use the MATCH and RETURN keywords to query data:

  • MATCH performs pattern matching to find content that matches a specified pattern.

  • RETURN specifies the values or results to return from the Cypher query.

Syntax:

SELECT * FROM cypher('graph_name', $$
  MATCH <patterns>
  RETURN <variables>
$$) AS (result1 agtype);

Examples:

  • Find all nodes with the Movie label.

    SELECT * FROM cypher('moviedb', $$
      MATCH (m:Movie)
      RETURN m
    $$) AS (result1 agtype);
  • Find edges labeled ACTED_IN that connect Person and Movie nodes.

    SELECT * FROM cypher('moviedb', $$
      MATCH (:Person)-[r:ACTED_IN]->(:Movie)
      RETURN r
    $$) AS (result1 agtype);

Data filtering

Use the WHERE clause to filter results when pattern matching and returning only a subset of interest. This clause lets you filter data using Boolean expressions.

Examples:

  • Find all movies titled The Matrix.

    SELECT * FROM cypher('moviedb', $$
      MATCH (m:Movie)
      WHERE m.title = 'The Matrix'
      RETURN m                     
    $$) AS (result1 agtype);
  • Find all actors in the movie Forrest Gump.

    SELECT * FROM cypher('moviedb', $$
      MATCH (p:Person)-[:ACTED_IN]->(m)
      WHERE m.title = 'Forrest Gump'
      RETURN p
    $$) AS (result1 agtype);
  • Find actors in movies released after 2000.

    SELECT * FROM cypher('moviedb', $$
      MATCH (p:Person)-[:ACTED_IN]->(m)
      WHERE m.released > 2000
      RETURN p, m
    $$) AS (result1 agtype, result2 agtype);

Create nodes or edges

In Cypher, use the CREATE keyword to add new nodes or edges.

Syntax:

SELECT * FROM cypher('<graph_name>', $$
  CREATE <patterns>
$$) AS (result1 agtype);

Examples:

  • Create a Person node with name Tom Tykwer and birth year 1965.

    SELECT * FROM cypher('moviedb', $$
      CREATE (:Person {name: 'Tom Tykwer', born: 1965})
    $$) AS (result1 agtype);
  • Create a Tom TykwerCloud Atlas edge indicating that Tom Tykwer directed Cloud Atlas.

    SELECT * FROM cypher('moviedb', $$
      MATCH (p:Person), (m:Movie)
      WHERE p.name='Tom Tykwer' AND m.title='Cloud Atlas'                 
      CREATE (p)-[:DIRECTED]->(m)
    $$) AS (result1 agtype);

Use MERGE to avoid duplicate inserts

Running the same CREATE statement multiple times inserts duplicate data. To prevent this, use the MERGE keyword. MERGE checks whether data already exists. If it does, it returns the existing data or updates the node or relationship. If not, it creates new data based on the specified pattern.

Syntax:

SELECT * FROM cypher('<graph_name>', $$
  MERGE <patterns>
$$) AS (result1 agtype);

Examples:

  • Create a Person node with name Tom Cruise and birth year 1962.

    SELECT * FROM cypher('moviedb', $$
      MERGE (:Person {name: 'Tom Cruise', born: 1962})
    $$) AS (result1 agtype);
  • Create a friendship edge between Tom Hanks and Tom Cruise.

    SELECT * FROM cypher('moviedb', $$
      MATCH (t1:Person),(t2:Person)
      WHERE t1.name='Tom Hanks' AND t2.name='Tom Cruise'                 
      MERGE (t1)-[:FRIEND]-(t2)
    $$) AS (result1 agtype);

Update

To modify properties of existing nodes or relationships, match the desired pattern and use the SET keyword to add or update properties.

Syntax:

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

Examples:

  • Change the birth year of Tom Tykwer to 1970.

    SELECT * FROM cypher('moviedb', $$
      MATCH (p:Person {name: 'Tom Tykwer', born: 1965})
      SET p.born = 1970
      RETURN p
    $$) AS (result1 agtype);
  • Add a gender property with value male to Tom Tykwer.

    SELECT * FROM cypher('moviedb', $$
      MATCH (p:Person {name: 'Tom Tykwer', born: 1970})
      SET p.gender = 'male'
      RETURN p
    $$) AS (result1 agtype);

Delete

In Cypher, use the DELETE keyword to remove nodes and edges.

Delete edges

To delete an edge, use MATCH to find the edge and DELETE to remove it.

Syntax

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

Example

Delete the DIRECTED edge between Tom Tykwer and the movie Cloud Atlas.

SELECT * FROM cypher('moviedb', $$
  MATCH (p:Person)-[r:DIRECTED]->(m:Movie)
  WHERE p.name='Tom Tykwer' AND m.title='Cloud Atlas'                 
  DELETE r
$$) AS (result1 agtype);

Delete nodes

To delete a node, use MATCH to find the node and DELETE to remove it.

Syntax

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

Example

Delete the Tom Tykwer node.

SELECT * FROM cypher('moviedb', $$
  MATCH (p:Person {name: 'Tom Tykwer', born: 1970})              
  DELETE p
$$) AS (result1 agtype);

Delete nodes and their edges

You cannot delete a node directly if it has connected edges. Use DETACH DELETE to remove all connected edges and then delete the node.

Syntax

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

Example

Delete the Tom Hanks node and all its connected edges.

SELECT * FROM cypher('moviedb', $$
  MATCH (p:Person {name: 'Tom Hanks', born: 1956})              
  DETACH DELETE p
$$) AS (result1 agtype);

Delete properties

To remove a property from a node or edge, use the REMOVE keyword.

Syntax

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

Example

Remove the released property from the movie Cloud Atlas.

SELECT * FROM cypher('moviedb', $$
  MATCH (m:Movie {title: 'Cloud Atlas', released: 2012})              
  REMOVE m.released
  RETURN m
$$) AS (result1 agtype);

Visualization tool

PolarDB for PostgreSQL integrates the open-source graph engine Apache AGE, letting you use both standard SQL and the industry-standard OpenCypher graph query language in the same cluster. This enables efficient storage, querying, and analysis of graph data for complex relationship scenarios. For more information, see Graph applications.

In AGE Viewer, run the Cypher query SELECT * from cypher('moviedb', $$ MATCH (V) RETURN V UNION MATCH ()-[r]->() RETURN r $$) as (V agtype); on the moviedb graph. The visualization shows three Movie nodes and three Person nodes (Tom Hanks, Keanu Reeves, Robert Zemeckis), along with two ACTED_IN edges and one DIRECTED edge, laid out using the Cose-Bilkent layout.