Created
November 23, 2023 15:01
-
-
Save Podbrushkin/3f16feb9b9da22ab27ee2878c38633aa to your computer and use it in GitHub Desktop.
Neo4j Embedded with Apoc plugin, export database to Cypher file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package myapp; | |
import java.io.IOException; | |
import java.nio.file.Path; | |
import java.util.List; | |
import java.util.Map; | |
import org.neo4j.configuration.connectors.BoltConnector; | |
import org.neo4j.configuration.helpers.SocketAddress; | |
import org.neo4j.dbms.api.DatabaseManagementServiceBuilder; | |
import org.neo4j.dbms.api.DatabaseManagementService; | |
import org.neo4j.driver.AuthTokens; | |
import org.neo4j.driver.GraphDatabase; | |
import org.neo4j.driver.TransactionContext; | |
import org.neo4j.exceptions.KernelException; | |
import org.neo4j.graphdb.GraphDatabaseService; | |
import org.neo4j.kernel.api.procedure.GlobalProcedures; | |
import org.neo4j.kernel.internal.GraphDatabaseAPI; | |
import apoc.ApocConfig; | |
import static org.neo4j.configuration.GraphDatabaseSettings.DEFAULT_DATABASE_NAME; | |
import static apoc.ApocConfig.apocConfig; | |
public class GraphApplication { | |
public static void main(String... a) throws IOException { | |
// This is the db itself, should be long-lived | |
var graphDb = new DatabaseManagementServiceBuilder(Path.of("target", "mydb")) | |
.setConfig(BoltConnector.enabled, true) | |
.setConfig(BoltConnector.listen_address, new SocketAddress("localhost", 7687)) | |
.setConfig(BoltConnector.encryption_level, BoltConnector.EncryptionLevel.DISABLED) | |
.build(); | |
var db = graphDb.database(DEFAULT_DATABASE_NAME); | |
registerProcedure(db, | |
apoc.export.cypher.ExportCypher.class); | |
// src: | |
// https://github.com/neo4j/apoc/blob/ed198fadfec318613de6bc6bd35276504915854c/core/src/test/java/apoc/export/BigGraphTest.java#L77 | |
apocConfig().setProperty(ApocConfig.APOC_EXPORT_FILE_ENABLED, true); | |
registerShutdownHook(graphDb); | |
// You could also use the graph database api and skip using bolt. | |
// The advantage of using build also in an embedded scenario: You can switch to | |
// a server with ease. | |
// Same goes for the driver with the connection pool | |
// The session itself is short-lived | |
try ( | |
var driver = GraphDatabase.driver("bolt://localhost:7687", AuthTokens.none()); | |
var session = driver.session()) { | |
session.executeWrite(t -> t.run( | |
"CREATE (p:Person {name: 'Arnold Schwarzenegger'}) - [:ACTED_IN] -> (:Movie {title: 'The Terminator'})") | |
.consume().counters().nodesCreated()); | |
var movies = session.executeRead(GraphApplication::findMovieAndTheirActors); | |
movies.forEach(System.out::println); | |
// src: | |
// https://neo4j.com/labs/apoc/4.1/export/cypher/#export-cypher-neo4j-browser | |
var query = """ | |
CALL apoc.export.cypher.all("all-plain.cypher", { | |
format: "plain", | |
useOptimizations: {type: "UNWIND_BATCH", unwindBatchSize: 20} | |
}) | |
"""; | |
session.executeRead(t -> t.run(query).consume()); | |
System.out.println("Dump of database has been created in /target/mydb/"); | |
} | |
// graphDb.shutdown(); | |
} | |
public static void registerProcedure(GraphDatabaseService db, Class<?>... procedures) { | |
GlobalProcedures globalProcedures = ((GraphDatabaseAPI) db).getDependencyResolver() | |
.resolveDependency(GlobalProcedures.class); | |
for (Class<?> procedure : procedures) { | |
try { | |
globalProcedures.registerProcedure(procedure); | |
globalProcedures.registerFunction(procedure); | |
globalProcedures.registerAggregationFunction(procedure); | |
} catch (KernelException e) { | |
throw new RuntimeException("while registering " + procedure, e); | |
} | |
} | |
} | |
private static void registerShutdownHook(final DatabaseManagementService managementService) { | |
// Registers a shutdown hook for the Neo4j instance so that it | |
// shuts down nicely when the VM exits (even if you "Ctrl-C" the | |
// running application). | |
Runtime.getRuntime().addShutdownHook(new Thread() { | |
@Override | |
public void run() { | |
System.out.println("Shutdown requested, please wait 3 seconds..."); | |
managementService.shutdown(); | |
System.out.println("Shutdown completed successfully."); | |
} | |
}); | |
} | |
record Person(String name) { | |
} | |
record Movie(String title, List<Person> actedIn) { | |
} | |
static List<Movie> findMovieAndTheirActors(TransactionContext tx) { | |
var query = """ | |
MATCH (m:Movie) <- [:ACTED_IN] - (p:Person) | |
WHERE m.title =~ $movieTitle | |
RETURN m.title AS title, collect(p.name) AS actors | |
"""; | |
return tx.run(query, Map.of("movieTitle", ".*The.*")).list(r -> { | |
var actors = r.get("actors").asList(v -> new Person(v.asString())); | |
return new Movie(r.get("title").asString(), actors); | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project xmlns="http://maven.apache.org/POM/4.0.0" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
<modelVersion>4.0.0</modelVersion> | |
<groupId>somegroup</groupId> | |
<artifactId>someapp</artifactId> | |
<version>1.0-SNAPSHOT</version> | |
<description> | |
Run it with `mvn clean compile exec:java` and you'll get a cypher dump file in `target/mydb/`. | |
</description> | |
<properties> | |
<maven.compiler.release>17</maven.compiler.release> | |
<neo4j.version>5.13.0</neo4j.version> | |
<exec.mainClass>myapp.GraphApplication</exec.mainClass> | |
</properties> | |
<dependencies> | |
<dependency> | |
<groupId>org.neo4j</groupId> | |
<artifactId>neo4j</artifactId> | |
<version>${neo4j.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.neo4j.driver</groupId> | |
<artifactId>neo4j-java-driver</artifactId> | |
<version>${neo4j.version}</version> | |
</dependency> | |
<!-- https://mvnrepository.com/artifact/org.neo4j.procedure/apoc-core --> | |
<dependency> | |
<groupId>org.neo4j.procedure</groupId> | |
<artifactId>apoc-core</artifactId> | |
<version>${neo4j.version}</version> | |
</dependency> | |
<!-- https://mvnrepository.com/artifact/org.neo4j.procedure/apoc-extended --> | |
<!-- This one not necessary --> | |
<!-- <dependency> | |
<groupId>org.neo4j.procedure</groupId> | |
<artifactId>apoc-extended</artifactId> | |
<version>${neo4j.version}</version> | |
</dependency> --> | |
<!-- https://mvnrepository.com/artifact/org.neo4j.procedure/apoc-common --> | |
<dependency> | |
<groupId>org.neo4j.procedure</groupId> | |
<artifactId>apoc-common</artifactId> | |
<version>${neo4j.version}</version> | |
</dependency> | |
</dependencies> | |
<build> | |
<plugins> | |
<plugin> | |
<groupId>org.apache.maven.plugins</groupId> | |
<artifactId>maven-compiler-plugin</artifactId> | |
<version>3.11.0</version> | |
</plugin> | |
</plugins> | |
</build> | |
</project> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment