Keep PostgreSQL and Neo4j in sync using Kafka Connector.
options
{Object}pgPool
{Pool} postgres client (must haveconnect()
method)neo4jClient
{GraphDatabase} neo4j client (must havecypher()
method)kafkaConsumer
{Consumer} kafka consumer (must haverun()
method)
options
{Object}tableName
{String} the name of the tablegetLabels
{Function} returns the labels for the nodegetProperties
{Function} returns the properties for the nodegetRelationships
{Function} returns the relationships for the node
options
{Object}tableName
{String} the name of the tablerow
{Object} the relational row data
- Returns {String} cypher query to create node
options
{Object}tableName
{String} the name of the tablerow
{Object} the relational row data
- Returns {String} cypher query to create relationships
CREATE TABLE cuisine (
id uuid,
name text
)
CREATE TABLE foods (
id uuid,
name text,
metadata jsonb
)
CREATE TABLE recipes (
id uuid,
name text,
cuisine_id uuid,
CONSTRAINT cuisine FOREIGN KEY (cuisine_id) REFERENCES cuisines (id)
)
CREATE TABLE ingredients (
recipe_id uuid,
food_id uuid,
CONSTRAINT recipe FOREIGN KEY (recipe_id) REFERENCES recipes (id),
CONSTRAINT food FOREIGN KEY (food_id) REFERENCES foods (id)
)
import GraphSync from 'graph-sync'
import pg from 'pg'
import neo4j from 'neo4j-driver'
import Kafka from 'kafka'
const pgPool = new pg.Pool()
const neo4jDriver = neo4j.driver()
const kafka = new Kafka()
const kafkaConsumer = kafka.consumer()
const graphSync = new GraphSync({ pgPool, neo4jDriver, kafkaConsumer })
// Specify the relational table and corresponding label for the graph.
await graphSync.registerTable({
tableName: 'cuisines',
getLabels: () => ['Cuisine']
})
// By default, all relational columns (except foreign keys) are saved
// as properties for the nodes in the graph. You can transform the
// data if you want different custom properties in the graph.
await graphSync.registerTable({
tableName: 'foods',
getLabels: row => row.isBeverage ? ['Beverage'] : ['Food'],
getProperties: row => ({ ...row, myCustomProperty: 123 })
})
// You can create one-to-many relationships between "this" node and
// another node using the name of the foreign key constraint.
await graphSync.registerTable({
tableName: 'recipes',
getLabels: () => ['Recipe'],
getRelationships: row => ['(this)-[:HAS_CUISINE]->(cuisine)']
})
// You can create many-to-many relationships between foreign keys.
// We've omitted a label, so it will not create a node on the graph.
await graphSync.registerTable({
tableName: 'ingredients',
getRelationships: row => ['(recipe)-[:HAS_INGREDIENT]->(food)']
})
// Generate the graph and sync it to Neo4j
await graphSync.initialLoad()
// Subscribe to the Kafka topic and update the graph
graphSync.listen()