Skip to content
Blog

Neo4j extension

The neo4j extension allows you to migrate your Neo4j data into a Kuzu database. It provides the following function:

  • NEO4J_MIGRATE: Migrate data from Neo4j to Kuzu

Usage

INSTALL neo4j;
LOAD neo4j;

Example dataset

The following queries create an example graph in Neo4j to demonstrate how this extension can be used. Ensure Neo4j is running, either as Neo4j Desktop or in Docker, and run the following Cypher queries:

// Create person nodes
CREATE (u:User {name: 'Adam', age: 30});
CREATE (u:User {name: 'Karissa', age: 40});
CREATE (u:User {name: 'Zhang', age: 50});
CREATE (u:User {name: 'Noura', age: 25});
// Create city nodes
CREATE (c:City {name: 'Waterloo', population: 150000});
CREATE (c:City {name: 'Kitchener', population: 200000});
CREATE (c:City {name: 'Guelph', population: 75000});
// Create person-city relationships
MATCH (u:User {name: 'Adam'}), (c:City {name: 'Waterloo'}) CREATE (u)-[:LivesIn]->(c);
MATCH (u:User {name: 'Karissa'}), (c:City {name: 'Waterloo'}) CREATE (u)-[:LivesIn]->(c);
MATCH (u:User {name: 'Zhang'}), (c:City {name: 'Kitchener'}) CREATE (u)-[:LivesIn]->(c);
MATCH (u:User {name: 'Noura'}), (c:City {name: 'Guelph'}) CREATE (u)-[:LivesIn]->(c);
// Create person-person relationships
MATCH (u:User {name: 'Adam'}), (u1:User {name: 'Karissa'}) CREATE (u)-[:Follows {since: 2020}]->(u1);
MATCH (u:User {name: 'Adam'}), (u1:User {name: 'Zhang'}) CREATE (u)-[:Follows {since: 2020}]->(u1);
MATCH (u:User {name: 'Karissa'}), (u1:User {name: 'Zhang'}) CREATE (u)-[:Follows {since: 2021}]->(u1);
MATCH (u:User {name: 'Zhang'}), (u1:User {name: 'Noura'}) CREATE (u)-[:Follows {since: 2022}]->(u1);

The queries above create a set of nodes of label User and City, and a set of relationships of label LivesIn and Follows.

Set up the Neo4j APOC extension

The Neo4j migration functionality relies on the APOC extension to be installed in Neo4j desktop or server. You can find details on how to install APOC in Neo4j here.

Also add the following config lines to the apoc.conf file:

apoc.export.file.enabled=true
apoc.import.file.use_neo4j_config=false

This doc provides instructions on Neo4j’s default conf file locations. The apoc.conf file may not exist in the conf directory, in which case, you would have to create a new one under the conf directory.

If you’re running Neo4j in Docker, you can use -e NEO4J_apoc_export_file_enabled=true -e NEO4J_apoc_import_file_use__neo4j__config=false to configure APOC. Additionally, you’ll need to mount /tmp as -v /tmp:/tmp to allow access to the exported data from Neo4j.

The following section shows how to migrate labels from Neo4j to tables in Kuzu.

Importing data from Neo4j

You can use the NEO4J_MIGRATE function to import data from Neo4j into Kuzu:

CALL NEO4J_MIGRATE(
<URL>,
<USER_NAME>,
<PASSWORD>,
[<NODE_LABEL1>, <NODE_LABEL2>, <NODE_LABEL3>, ...], // NODE_LABELS
[<REL_LABEL1>, <REL_LABEL2>, <REL_LABEL3>, ...] // REL_LABELS
);
  • URL: A http://hostname:port connection URL to a Neo4j server.
    • Type: STRING
  • USER_NAME: Neo4j username. Leave blank if not needed.
    • Type: STRING
  • PASSWORD: Neo4j password. Leave blank if not needed.
    • Type: STRING
  • NODE_LABELS: A list of node labels to migrate to Kuzu. Use ["*"] to import all nodes with labels.
    • Type: STRING[]
  • REL_LABELS: A list of relationship labels to migrate to Kuzu. Use ["*"] to import all relationships with labels.
    • Type: STRING[]

Example

For the example dataset, you can import the User and City node tables, and the LivesIn and Follows relationship tables:

CALL NEO4J_MIGRATE(
"http://localhost:7474",
"neo4j",
"neo4jpassword",
["User", "City"],
["Follows", "LivesIn"]
);

Alternatively, you can import all nodes and relationships:

CALL NEO4J_MIGRATE(
"http://localhost:7474",
"neo4j",
"neo4jpassword",
["*"],
["*"]
);

You can use SHOW_TABLES() to verify that the tables have been imported into Kuzu:

CALL SHOW_TABLES() RETURN *;
┌────────┬─────────┬────────┬───────────────┬─────────┐
│ id │ name │ type │ database name │ comment │
│ UINT64 │ STRING │ STRING │ STRING │ STRING │
├────────┼─────────┼────────┼───────────────┼─────────┤
│ 0 │ User │ NODE │ local(kuzu) │ │
│ 2 │ Follows │ REL │ local(kuzu) │ │
│ 1 │ City │ NODE │ local(kuzu) │ │
│ 3 │ LivesIn │ REL │ local(kuzu) │ │
└────────┴─────────┴────────┴───────────────┴─────────┘

The data from Neo4j is now available in Kuzu and you can start querying them. For example, let’s find the user who was most recently followed by another user:

MATCH (u:User)-[f:Follows]->(u1:User)
RETURN u.name
ORDER BY f.since
DESC LIMIT 1;
┌────────┬─────────┐
│ u.name │ f.since │
│ STRING │ INT64 │
├────────┼─────────┤
│ Zhang │ 2022 │
└────────┴─────────┘