Tried out the new feature BigQuery Graph

Tried out the new feature BigQuery Graph

2026.04.27

This page has been translated by machine translation. View original

I am from the Data Business Division, Hanzawa.

On April 9th, BigQuery Graph was announced as a new feature.

Until now, BigQuery had a strong image primarily as an analytical platform for data warehousing, but going forward, its range of applications will likely expand to cases handling graph data.
Additionally, this feature was prominently highlighted at Google Cloud Next '26 held in Las Vegas until recently, indicating it's a highly anticipated feature.

https://cloud.google.com/blog/products/data-analytics/unveiling-new-bigquery-capabilities-for-the-agentic-era?hl=en

Although I don't have previous experience with graph databases (GDB), I'd like to try it out.

What is a Graph Database (GDB)?

https://cloud.google.com/discover/what-is-a-graph-database?hl=ja

A graph database (GDB) is a type of NoSQL database that uses a graph structure consisting of nodes and edges to represent entities and their relationships.

  • Nodes

    • Simply put, they are points
    • Entities that represent real objects like people, products, or places
  • Edges

    • Simply put, they are lines
    • Elements that represent relationships between nodes
    • For example, the relationship between a "customer" node and a "product" node can be expressed as "purchased."

Comparing relational databases (RDB) and graph databases (GDB) from various perspectives:

Feature Relational Database (RDB) Graph Database (GDB)
Data Structure Tabular format with rows and columns
Handled with strict schemas with predefined properties
Graph structure with nodes and edges
Flexible representation of relationships
Query Efficiency JOIN operations to combine tables; queries can become slower or more complex as relationships increase Can directly traverse edges; queries focusing on relationships tend to be more intuitive
Query Language SQL (Structured Query Language) GQL (Graph Query Language)
Use Cases Suitable for structured, predictable business data like financial systems or inventory management Suitable for applications centered on relationship analysis like social networks, fraud detection, or path optimization

What is GQL?

https://docs.cloud.google.com/bigquery/docs/reference/standard-sql/graph-intro

BigQuery Graph uses GQL (Graph Query Language) to query graph data.
GQL syntax differs significantly from traditional SQL, so it might take some time to get used to it.
The following documentation provides helpful information about specific syntax.

https://docs.cloud.google.com/bigquery/docs/reference/standard-sql/graph-query-statements

For example, if you want to retrieve all "product names" that "Customer A" has purchased:

In this case, the query would be as follows:

GRAPH ShopGraph
MATCH (c:Customer {customer_name: 'A'})-[:purchased]->(p:Product)
RETURN p.product_name

In this query, GRAPH specifies the target graph, and MATCH traverses the relationship between nodes and edges. Inside {}, you can specify node property conditions, in this case representing customers with customer_name equal to A. Finally, RETURN returns the product names you want to retrieve.

Conversely, if you want to retrieve all customer names who purchased "Product B":

In this case, the query would be:

GRAPH ShopGraph
MATCH (p:Product {product_name: 'B'})<-[:purchased]-(c:Customer)
RETURN c.customer_name

While the first query traversed from "Customer" to "Product," this query traverses in the opposite direction from "Product" to "Customer." Therefore, the direction of the purchased edge is written as <-[:purchased]- to indicate the reverse direction.

These patterns are described as graph patterns within the MATCH statement. Please also check the following documentation for more details.

https://docs.cloud.google.com/bigquery/docs/reference/standard-sql/graph-patterns

Finally, let's try a slightly more complex example.
The following query retrieves the "customer names" and "product names" of customers who purchased the same products as "Customer A":

GRAPH ShopGraph
MATCH (a:Customer {customer_name: 'A'})-[:purchased]->(p:Product)<-[:purchased]-(c:Customer)
WHERE c != a
RETURN c.customer_name, p.product_name

This query can also be written step by step using the NEXT statement. NEXT passes the results from the previous step to the next step.
FILTER is a syntax that applies conditions to the result rows, similar in appearance to WHERE, but it can reference columns passed from the previous step. Here, c != a excludes Customer A themselves.

GRAPH ShopGraph
MATCH (a:Customer {customer_name: 'A'})-[:purchased]->(p:Product)
RETURN a, p

NEXT

MATCH (p)<-[:purchased]-(c:Customer)
FILTER c != a
RETURN c.customer_name, p.product_name

What I've introduced so far is just a part of the basic GQL syntax. Please also check the official documentation mentioned above for more detailed syntax.

Let's Try It Out

Now, I'd like to actually reproduce the examples I introduced earlier on BigQuery Graph.

1. Preparing Sample Data

First, let's prepare the sample data.

To represent the above relationship, I'll create the following 3 tables:

  1. Customer table
  2. Product table
  3. Bridge table representing the purchasing relationship between customers and products

Tables 1 and 2 will be treated as nodes, and table 3 as edges, but they are created as regular tables.

Customer table
CREATE OR REPLACE TABLE `sample_graph.customers` (
  customer_id INT64 PRIMARY KEY NOT ENFORCED,
  customer_name STRING
);

INSERT INTO `sample_graph.customers` (customer_id, customer_name)
VALUES
  (1, 'A さん'),
  (2, 'B さん'),
  (3, 'C さん'),
  (4, 'D さん'),
  (5, 'E さん');
Product table
CREATE OR REPLACE TABLE `sample_graph.products` (
  product_id INT64 PRIMARY KEY NOT ENFORCED,
  product_name STRING,
  category STRING,
  price INT64
);

INSERT INTO `sample_graph.products` (product_id, product_name, category, price)
VALUES
  (101, 'りんご', '食品', 120),
  (102, 'ミネラルウォーター', '飲料', 180),
  (103, 'ノート', '文房具', 150),
  (104, 'ボールペン', '文房具', 200),
  (105, 'トイレットペーパー', '日用品', 300),
  (106, 'コーヒー豆', '食品', 450),
  (107, 'ワイヤレスイヤホン', '家電', 1200),
  (108, 'モバイルバッテリー', '家電', 2400);
Bridge table
CREATE OR REPLACE TABLE `sample_graph.customer_product_bridge` (
  purchase_id INT64 PRIMARY KEY NOT ENFORCED,
  customer_id INT64 REFERENCES `sample_graph.customers` (customer_id) NOT ENFORCED,
  product_id INT64 REFERENCES `sample_graph.products` (product_id) NOT ENFORCED,
  purchased_at DATE
);

INSERT INTO `sample_graph.customer_product_bridge`
  (purchase_id, customer_id, product_id, purchased_at)
VALUES
  (1, 1, 101, DATE '2026-04-01'),  -- A さん -> りんご
  (2, 1, 102, DATE '2026-04-02'),  -- A さん -> ミネラルウォーター
  (3, 1, 103, DATE '2026-04-03'),  -- A さん -> ノート
  (4, 2, 102, DATE '2026-04-02'),  -- B さん -> ミネラルウォーター
  (5, 2, 104, DATE '2026-04-03'),  -- B さん -> ボールペン
  (6, 2, 105, DATE '2026-04-04'),  -- B さん -> トイレットペーパー
  (7, 3, 101, DATE '2026-04-01'),  -- C さん -> りんご
  (8, 3, 102, DATE '2026-04-02'),  -- C さん -> ミネラルウォーター
  (9, 3, 106, DATE '2026-04-05'),  -- C さん -> コーヒー豆
  (10, 4, 103, DATE '2026-04-03'), -- D さん -> ノート
  (11, 4, 107, DATE '2026-04-06'), -- D さん -> ワイヤレスイヤホン
  (12, 5, 102, DATE '2026-04-02'), -- E さん -> ミネラルウォーター
  (13, 5, 103, DATE '2026-04-03'), -- E さん -> ノート
  (14, 5, 108, DATE '2026-04-07'); -- E さん -> モバイルバッテリー

2. Creating a Property Graph

https://docs.cloud.google.com/bigquery/docs/reference/standard-sql/graph-schema-statements

A property graph can be created using the CREATE PROPERTY GRAPH syntax.

In NODE TABLES, specify the tables corresponding to nodes, and in EDGE TABLES, specify the tables corresponding to edges. Additionally, in EDGE TABLES, you can specify SOURCE KEY and DESTINATION KEY to express which nodes are connected.

CREATE OR REPLACE PROPERTY GRAPH sample_graph.ShopGraph
  NODE TABLES (
    `sample_graph.customers` AS Customer
      LABEL customer,
    `sample_graph.products` AS Product
      LABEL product
  )
  EDGE TABLES (
    `sample_graph.customer_product_bridge` AS Purchase
      SOURCE KEY (customer_id) REFERENCES Customer (customer_id)
      DESTINATION KEY (product_id) REFERENCES Product (product_id)
  );

In the end, the dataset structure looks like this:

Screenshot 2026-04-27 9.35.34

Additionally, you can visually confirm the relationships between nodes from the console.

Screenshot 2026-04-27 10.25.37

3. Trying It Out

Following the previous examples, I'll try these 3 patterns:

  1. Retrieve all product names purchased by Customer A
  2. Retrieve customer names who purchased mineral water
  3. Retrieve customer names and product names of customers who purchased the same products as Customer A

3.1. Retrieve all product names purchased by Customer A

GRAPH sample_graph.ShopGraph
MATCH (c:customer {customer_name: 'A さん'})-[:Purchase]->(p:product)
RETURN p.product_name

We can see that the products purchased by Customer A are apple, mineral water, and notebook.

Screenshot 2026-04-27 10.50.39

3.2. Retrieve customer names who purchased mineral water

GRAPH sample_graph.ShopGraph
MATCH (p:product {product_name: 'ミネラルウォーター'})<-[:Purchase]-(c:customer)
RETURN c.customer_name

We can see that Customers A, B, C, and E purchased mineral water.

Screenshot 2026-04-27 10.51.41

3.3. Retrieve customer names and product names of customers who purchased the same products as Customer A

GRAPH sample_graph.ShopGraph
MATCH (a:customer {customer_name: 'A さん'})-[:Purchase]->(p:product)
RETURN a, p

NEXT

MATCH (p)<-[:Purchase]-(c:customer)
FILTER c != a
RETURN c.customer_name, p.product_name

Screenshot 2026-04-27 10.52.44

Additionally, you can use GQL execution results in SQL:

SELECT
  customer_name,
  product_name
FROM
  GRAPH_TABLE(
    sample_graph.ShopGraph
    MATCH (a:customer {customer_name: 'A さん'})-[:Purchase]->(p:product)
    RETURN a, p

    NEXT

    MATCH (p)<-[:Purchase]-(c:customer)
    FILTER c != a
    RETURN c.customer_name, p.product_name
  )
ORDER BY customer_name;

Screenshot 2026-04-27 19.29.53

Bonus

The documentation introduces best practices for graph schema design and querying. Please check them out as well.

https://docs.cloud.google.com/bigquery/docs/graph-schema-best-practices

https://docs.cloud.google.com/bigquery/docs/graph-query-best-practices

Also, several official tutorials are available, so please try them if you're interested.

https://codelabs.developers.google.com/codelabs/fraud-bigquery-graph?hl=ja

https://codelabs.developers.google.com/codelabs/c360-bigquery-graph?hl=ja

https://codelabs.developers.google.com/codelabs/supplychaingraph?hl=ja

Conclusion

In this blog, I tried out the new BigQuery Graph feature. It was also a good opportunity to understand the basics of graph databases.

Furthermore, on April 22nd, new features for BigQuery Graph were added, such as defining measures and querying graphs in natural language through Conversational Analytics. Expectations for future developments are high.

Going forward, I'd like to try these features as well.

Share this article