Logo

dev-resources.site

for different kinds of informations.

YugabyteDB as a Graph database with PuppyGraph

Published at
10/7/2024
Categories
yugabytedb
graph
postgres
database
Author
franckpachot
Author
12 person written this
franckpachot
open
YugabyteDB as a Graph database with PuppyGraph

PostgreSQL can handle any workload without streaming data to a purpose-built database. This includes graph databases using PuppyGraph, which maps relational tables to a graph model.
When resilience, scalability, and elasticity are necessary, YugabyteDB provides a distributed alternative to PostgreSQL.

This article details the step-by-step tutorial to using PuppyGraph to query data in PostgreSQL, but using YugabyteDB instead of PostgreSQL.


Deployment

I Create a file docker-compose.yaml with the following content:

services:
  puppygraph:
    image: puppygraph/puppygraph:stable
    pull_policy: always
    container_name: puppygraph
    environment:
      - PUPPYGRAPH_USERNAME=puppygraph
      - PUPPYGRAPH_PASSWORD=puppygraph123
    networks:
      yugabytedb_net:
    ports:
      - "8081:8081"
      - "8182:8182"
      - "7687:7687"
  yugabytedb:
    image: yugabytedb/yugabyte:2024.1.2.0-b77
    command: yugabyted start --enable_pg_parity_tech_preview --background=false
    environment:
      - YSQL_USER=puppygraph
      - YSQL_PASSWORD=puppygraph123
    networks:
      yugabytedb_net:
    ports:
      - "5433:5433"
    volumes:
      - ./yugabyte-data:/root/var/data
networks:
  yugabytedb_net:
    name: puppy-yugabytedb
Enter fullscreen mode Exit fullscreen mode

I run the following command to start YugabyteDB and PuppyGraph:

docker compose up -d
Enter fullscreen mode Exit fullscreen mode

I can connect on http://localhost:8080/

Image description

Image description


Data Preparation

I run the following command to start ysqlsh, the PostgreSQL shell, to access the database:


docker compose run -it -e PGPASSWORD=puppygraph123 -e PGUSER=puppygraph -e PGHOST=yugabytedb -e PGPORT=5433 -e PGDATABASE=yugabyte yugabytedb ysqlsh 

Enter fullscreen mode Exit fullscreen mode

I execute the following SQL statements in the shell to create tables and insert data:

create schema modern;
create table modern.person (id text, name text, age integer);
insert into modern.person values
                              ('v1', 'marko', 29),
                              ('v2', 'vadas', 27),
                              ('v4', 'josh', 32),
                              ('v6', 'peter', 35);

create table modern.software (id text, name text, lang text);
insert into modern.software values
                                ('v3', 'lop', 'java'),
                                ('v5', 'ripple', 'java');

create table modern.created (id text, from_id text, to_id text, weight double precision);
insert into modern.created values
                               ('e9', 'v1', 'v3', 0.4),
                               ('e10', 'v4', 'v5', 1.0),
                               ('e11', 'v4', 'v3', 0.4),
                               ('e12', 'v6', 'v3', 0.2);

create table modern.knows (id text, from_id text, to_id text, weight double precision);
insert into modern.knows values
                             ('e7', 'v1', 'v2', 0.5),
                             ('e8', 'v1', 'v4', 1.0);

analyze;

Enter fullscreen mode Exit fullscreen mode

Modeling a Graph

I use the PuppyGraph schema file schema.json with the following content:

{
  "catalogs": [
    {
      "name": "postgres_data",
      "type": "postgresql",
      "jdbc": {
        "username": "puppygraph",
        "password": "puppygraph123",
        "jdbcUri": "jdbc:postgresql://yugabytedb:5433/yugabyte",
        "driverClass": "org.postgresql.Driver"
      }
    }
  ],
  "vertices": [
    {
      "label": "person",
      "mappedTableSource": {
        "catalog": "postgres_data",
        "schema": "modern",
        "table": "person",
        "metaFields": {
          "id": "id"
        }
      },
      "attributes": [
        {
          "type": "Int",
          "name": "age"
        },
        {
          "type": "String",
          "name": "name"
        }
      ]
    },
    {
      "label": "software",
      "mappedTableSource": {
        "catalog": "postgres_data",
        "schema": "modern",
        "table": "software",
        "metaFields": {
          "id": "id"
        }
      },
      "attributes": [
        {
          "type": "String",
          "name": "lang"
        },
        {
          "type": "String",
          "name": "name"
        }
      ]
    }
  ],
  "edges": [
    {
      "label": "knows",
      "mappedTableSource": {
        "catalog": "postgres_data",
        "schema": "modern",
        "table": "knows",
        "metaFields": {
          "id": "id",
          "from": "from_id",
          "to": "to_id"
        }
      },
      "from": "person",
      "to": "person",
      "attributes": [
        {
          "type": "Double",
          "name": "weight"
        }
      ]
    },
    {
      "label": "created",
      "mappedTableSource": {
        "catalog": "postgres_data",
        "schema": "modern",
        "table": "created",
        "metaFields": {
          "id": "id",
          "from": "from_id",
          "to": "to_id"
        }
      },
      "from": "person",
      "to": "software",
      "attributes": [
        {
          "type": "Double",
          "name": "weight"
        }
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

I upload the schema by selecting the file schema.json in the

Image description

Image description

Querying the graph via CLI

I execute the following command to access the PuppyGraph Gremlin Console

docker compose exec -it puppygraph ./bin/console
Enter fullscreen mode Exit fullscreen mode

I run the following queries in the console to query the Graph:

puppy-gremlin> g.V().has("name", "marko").valueMap()
Done! Elapsed time: 0.359s, rows: 1
==>map[age:29 name:marko]
puppy-gremlin> g.V().has("name", "marko").out("knows").out("created").valueMap()
Done! Elapsed time: 0.108s, rows: 2
==>map[lang:java name:lop]
==>map[lang:java name:ripple]
puppy-gremlin>
Enter fullscreen mode Exit fullscreen mode

SQL Queries

I refresh the local cache to check from pg_stat_statements that the queries are fast:

Image description

yugabyte=# select total_time/calls as time, calls, substr(query,1,80)
 from pg_stat_statements order by 1
;
Enter fullscreen mode Exit fullscreen mode

Image description

Scale-Out YugabyteDB

To add more nodes to the YugabyteDB cluster, you can add a service that starts YugabyteDB and join the first node. Add the following to docker-compose.yaml:

  more-nodes:
    image: yugabytedb/yugabyte:2024.1.2.0-b77
    command: yugabyted start --join yugabytedb --enable_pg_parity_tech_preview --background=false
    networks:
      yugabytedb_net:
    deploy:
     replicas: 0
Enter fullscreen mode Exit fullscreen mode

Start a second node with:

docker compose up -d --scale more-nodes=1
Enter fullscreen mode Exit fullscreen mode

Start a third node with:

docker compose up -d --scale more-nodes=2
Enter fullscreen mode Exit fullscreen mode

With three nodes, the cluster is automatically set to Replication Factor 3 and becomes resilient to one node failure

Conclusion

This tutorial demonstrates using PuppyGraph to query YugabyteDB as a graph database, leveraging the PostgreSQL compatibility of YugabyteDB's distributed architecture. It follows the simple deployment steps from PuppyGraph documentation.

With PuppyGraph, you can directly query your existing data stores without needing ETL pipelines. PuppyGraph and YugabyteDB together provide a powerful solution for modern graph-based analytics.


YugabyteDB. The Distributed SQL Database for Mission-Critical Apps

YugabyteDB is the 100% open source cloud native database for mission critical applications. YugabyteDB runs in any public or hybrid cloud.

favicon yugabyte.com
graph Article's
30 articles in total
Favicon
Get a gist of graph data structure here...
Favicon
Find safest walk through the grid
Favicon
Number of islands
Favicon
Negative cycle with Dijskta(Possible but not optimal)
Favicon
YugabyteDB as a Graph database with PuppyGraph
Favicon
Remove Methods from project
Favicon
Visualize the preferences of cats
Favicon
How to Determine if a Graph is Not Simple Without Checking Every Edge for Loops or Parallelism
Favicon
Disjoint Set Graph Learning
Favicon
Bellman ford algorithm(Single Source Shorted Path in DAG)
Favicon
Safely restructure your codebase with Dependency Graphs
Favicon
Unveiling the Connections: A Beginner's Guide to Graph Theory
Favicon
How is Graph stored in Memory?
Favicon
Graph problems are not hard
Favicon
Como andam as suas Relações?
Favicon
Merge Intervals : A unique Graph-based approach
Favicon
Explaining LinkedIn profile, "1st," "2nd," and "3rd" values.
Favicon
Neo4j and the Power of Graph Databases in Data Science
Favicon
Exploring the Implementation of Graph Data in OceanBase
Favicon
Solving "Word Search" problem
Favicon
Powershell script to call microsoft graph and send email using azure app registration
Favicon
A developer’s introduction to graph databases
Favicon
Graph in R with Grouping Letters from the Tukey, LSD, Duncan Test, agricolae Package
Favicon
How to: Get up to speed and scale with Aerospike Graph on Google Cloud Marketplace
Favicon
Preview Geometry Nodes on web using React
Favicon
Improved Data Point Graph Widget for Cumulocity IoT
Favicon
Six Degrees of Separation Using Apache AGE
Favicon
Next Big Data System
Favicon
The Usability of Graph Data and Graph Algorithms: Unleashing the Power of Connections
Favicon
Accelerate Domain Learning: Explore Application Dependencies with RailsGraph

Featured ones: