Using the Bolt protocol to make openCypher queries to Neptune - Amazon Neptune

Using the Bolt protocol to make openCypher queries to Neptune

Bolt is a statement-oriented client/server protocol initially developed by Neo4j and licensed under the Creative Commons 3.0 Attribution-ShareAlike license. It is client-driven, meaning that the client always initiates message exchanges.

To connect to Neptune using Neo4j's Bolt drivers, simply replace the URL and Port number with your cluster endpoints using the bolt+s URI scheme. If you have a single Neptune instance running, use the read_write endpoint. If multiple instances are running, then two drivers are recommended, one for the writer and another for all the read replicas. If you have only the default two endpoints, a read_write and a read_only driver are sufficient, but if you have custom endpoints as well, consider creating a driver instance for each one.

Neptune supports the latest Neo4j drivers for Bolt message specification versions: 4.0.3, 4.1.4, 4.2.7 and 4.3.3.

For examples of openCypher queries in various languages that use the Bolt drivers, see the Neo4j Drivers & Language Guides documentation.

Using Bolt with Java to connect to Neptune

You can download a driver for whatever version you want to use from the Maven MVN repository, or can add this dependency to your project:

<dependency> <groupId>org.neo4j.driver</groupId> <artifactId>neo4j-java-driver</artifactId> <version>4.3.3</version> </dependency>

Then, to connect to Neptune in Java using one of these Bolt drivers, create a driver instance for the primary/writer instance in your cluster using code like the following:

import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; Driver driver = GraphDatabase.driver("bolt+s://(your cluster endpoint URL):8182");

If you have one or more reader replicas, you can similarly create a driver instance for them using code like this:

Driver read_only_driver = GraphDatabase.driver("bolt+s://(your cluster endpoint URL):8182"; Driver read_only_driver_with_timeout = GraphDatabase.driver("bolt+s://(your cluster endpoint URL):8182", Config.builder().withConnectionTimeout(30, TimeUnit.SECONDS).build());

If you have custom endpoints, it may also be worthwhile to create a driver instance for each one.

A Python openCypher query example using Bolt

Here is how to make an openCypher query in Python using Bolt:

python -m pip install neo4j
from neo4j import GraphDatabase
from neo4j import GraphDatabase uri = "bolt+s://(your cluster endpoint URL):8182" driver = GraphDatabase.driver(uri, auth=("", "")

Or, with encryption:

from neo4j import GraphDatabase uri = "bolt+s://(your cluster endpoint URL):8182" driver = GraphDatabase.driver(uri, auth=("", "", encrypted=True)

Note that the auth parameters are ignored. You can then use your driver instance like this:

def create_friend_of(tx, name, friend): tx.run(f"MATCH (a:Person) WHERE a.name = '" + friend + "'" "CREATE (a)-[:KNOWS]->(:Person {name: $friend})", name=name, friend=friend) with driver.session() as session: session.write_transaction(create_friend_of, "Alice", "Bob") with driver.session() as session: session.write_transaction(create_friend_of, "Alice", "Carl") driver.close()

A .NET openCypher query example using Bolt

Here is how to make an openCypher query in .NET using Bolt:

Install-Package Neo4j.Driver-4.3.0
Using Neo4j.Driver-4.3.0; var driver = GraphDatabase.Driver("bolt+s://(your cluster endpoint URL):8182", AuthTokens.Basic("", "")); public class HelloWorldExample : IDisposable { private bool _disposed = false; ~HelloWorldExample() => Dispose(false); public void PrintGreeting(string message) { using (var session = driver.Session()) { var greeting = session.WriteTransaction(tx => { var result = tx.Run("CREATE (a:Greeting) " + "SET a.message = '" + message + "'" "RETURN a.message + ', from node ' + id(a)", new {message}); return result.Single()[0].As<string>(); }); Console.WriteLine(greeting); } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (_disposed) return; _disposed = true; } public static void Main() { using (var greeter = new HelloWorldExample( )) { greeter.PrintGreeting("hello, world"); } } }

Bolt connection behavior in Neptune

Here are some things to keep in mind about Neptune Bolt connections:

  • Because Bolt connections are created at the TCP layer, you can't use an Application Load Balancer in front of them, as you can with an HTTP endpoint.

  • The port that Neptune uses for Bolt connections is 8182.

  • Based on the Bolt preamble passed to it, the Neptune server selects the highest appropriate Bolt version (1, 2, 3, or 4.2).

  • The maximum number of connections to the Neptune server that a client can have open at any point in time is 1,000.

  • If the client doesn't close a connection after a query, that connection can be used to execute the next query.

  • However, if a connection is idle for 20 minutes, the server closes it automatically.

  • When IAM authentication is enabled, a Bolt connection is always disconnected a few minutes more than 10 days after it was established if it hasn't already closed for some other reason.

  • If the client sends a query for execution over a connection without having consumed the results of a previous query, the new query is discarded. To discard the previous results instead, the client must send a reset message over the connection.

  • Only one transaction at a time can be created on a given connection.

  • If an exception occurs during a transaction, the Neptune server rolls back the transaction and closes the connection. In this case, the driver creates a new connection for the next query.

  • Be aware that sessions are not thread-safe. Multiple parallel operations must use multiple separate sessions.

Important

Special feedback link:   If you encounter any problems using openCypher in this Neptune lab-mode release or have suggestions, please email us at . We're here to help.