• Stars
    star
    231
  • Rank 173,434 (Top 4 %)
  • Language
    C#
  • License
    Apache License 2.0
  • Created almost 9 years ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Neo4j Bolt driver for .NET

Neo4j .NET Driver

This is the official Neo4j driver for .NET.

Resources to get you started:

For Application Developers

This section is prepared for application developers who would like to use this driver in application projects for connecting to a Neo4j instance or a Neo4j cluster.

For users who wish to migrate from 1.7 series to 4.0, checkout our migration guide.

Versions

Starting with 5.0, the Neo4j Drivers will be moving to a monthly release cadence. A minor version will be released on the last Friday of each month so as to maintain versioning consistency with the core product (Neo4j DBMS) which has also moved to a monthly cadence.

As a policy, patch versions will not be released except on rare occasions. Bug fixes and updates will go into the latest minor version and users should upgrade to that. Driver upgrades within a major version will never contain breaking API changes(Excluding the Neo4j.Driver.Preview namespace).

See also: https://neo4j.com/developer/kb/neo4j-supported-versions/

Getting the Driver

The Neo4j driver is distributed under three packages:

Add the asynchronous driver to your project using the Nuget Package Manager:

PM> Install-Package Neo4j.Driver

There is also a strong named version of each driver package available on Nuget such as Neo4j.Driver.Signed. Both packages contain the same version of the driver, only the latter is strong named. Consider using the strong named version only if your project is strong named and/or you are forced to use strong named dependencies.

Add the strong named version of the asynchronous driver to your project using the Nuget Package Manager:

PM> Install-Package Neo4j.Driver.Signed

Minimum Viable Snippet

Connect to a Neo4j database

using var driver = GraphDatabase.Driver("bolt://localhost:7687", AuthTokens.Basic("neo4j", "password"));
var queryOperation = await driver.ExecutableQuery("CREATE (n) RETURN n").ExecuteAsync();

There are a few points that need to be highlighted when adding this driver into your project:

  • Each IDriver instance maintains a pool of connections inside; as a result, it is recommended that you use only one driver per application.
  • It is considerably cheap to create new sessions and transactions, as sessions and transactions do not create new connections as long as there are free connections available in the connection pool.
  • The driver is thread-safe, while the session or the transaction is not thread-safe.

Parsing Result Values

Query Execution Result

The result of executing a query in the way shown above is an EagerResult<T>, where T is the type of data returned from the query. In the simplest case, this will be an IReadOnlyList<IRecord>, which is a fully materialized list of the records returned by the query. Other types of results can be used by using the fluent API exposed by the IExecutableQuery type.

Examples
var queryOp = await driver
    .ExecutableQuery("MATCH (person:Person) RETURN person")
    .WithMap(r => r["person"].As<INode>()["name"].As<string>())
    .ExecuteAsync();
// queryOp.Result is IReadOnlyList<string>

var queryOp = await driver
    .ExecutableQuery("MATCH (person:Person) RETURN person")
    .WithMap(r => r["person"].As<INode>()["name"].As<string>())
    .WithFilter(s => s.StartsWith("A"))
    .ExecuteAsync();
// queryOp.Result is IReadOnlyList<string> - note that this type of filtering 
// is done on the client and is not a substitute for filtering in the Cypher

var queryOp = await driver
    .ExecutableQuery("MATCH (person:Person) RETURN person")
    .WithMap(r => r["person"].As<INode>()["age"].As<int>())
    .WithReduce(() => 0, (r, n) => r + n)
    .ExecuteAsync();
// queryOp.Result is `int`, the sum of all the ages

var queryOp = await driver
    .ExecutableQuery("MATCH (person:Person) RETURN person")
    .WithStreamProcessor(
        async stream =>
        {
            double total = 0;
            int count = 0;

            await foreach(var record in stream)
            {
                var ages = record["person"].As<INode>()["age"].As<string>();
                total += age;
                count++;
            }

            return total / count;
        })
    .ExecuteAsync();
// queryOp.Result is `double`, the average of all the ages

Record Stream

A cypher execution result is comprised of a stream records followed by a result summary. The stream can be accessed directly by using the WithStreamProcessor method as shown above. The stream implements IAsyncEnumerable<IRecord> and as such can be accessed with normal Linq methods by adding the System.Linq.Async package to your project. The ExecuteAsync method will return an EagerResult<T>, where T is the type of value returned from the method passed to WithStreamProcessor. This value will be stored in the Result property of the EagerResult, with the Summary and Keys property containing further information about the execution of the query.

Value Types

Values in a record are currently exposed as of object type. The underlying types of these values are determined by their Cypher types.

The mapping between driver types and Cypher types are listed in the table bellow:

Cypher Type Driver Type
null null
List IList< object >
Map IDictionary<string, object>
Boolean boolean
Integer long
Float float
String string
ByteArray byte[]
Point Point
Node INode
Relationship IRelationship
Path IPath

To convert from object to the driver type, a helper method ValueExtensions#As<T> can be used:

IRecord record = await result.SingleAsync();
string name = record["name"].As<string>();

Temporal Types - Date and Time

The new temporal types in Neo4j 3.4 series are introduced with the 1.6 series of the driver. Considering the nanosecond precision and large range of supported values, all temporal types are backed by custom types at the driver level.

The mapping among the Cypher temporal types, driver types, and convertible CLR temporal types - DateTime, TimeSpan and DateTimeOffset - (via IConvertible interface) are as follows:

Cypher Type Driver Type Convertible CLR Type
Date LocalDate DateTime
Time OffsetTime ---
LocalTime LocalTime TimeSpan, DateTime
DateTime ZonedDateTime DateTimeOffset
LocalDateTime LocalDateTime DateTime
Duration Duration ---

Receiving a temporal value as driver type:

IRecord record = await result.SingleAsync();
ZonedDateTime datetime = record["datetime"].As<ZonedDateTime>();

Converting a temporal value to the CLR type:

object record = await result.SingleAsync()["datetime"];

DateTimeOffset datetime = record["datetime"].As<DateTimeOffset>();
// which is equivalent to
// ZonedDateTime cyDatetime = record["datetime"].As<ZonedDateTime>();
// DateTimeOffset datetime = cyDatetime.ToDateTimeOffset();

Note:

  • The conversion to CLR types is possible only when the value fits in the range of the target built-in type. A ValueOverflowException is thrown when the conversion is not possible.
  • The Cypher temporal types (excluding Date) provide nanosecond precision. However CLR types only support ticks (100 nanosecond) precision. So a temporal type created via Cypher might not be convertible to the CLR type (a ValueTruncationException is thrown when a conversion is requested in this case).
  • ZonedDateTime represents date and times with either offset or time zone information. Time zone names adhere to the IANA system, rather than the Windows system. Although there is no support for inbound time zone name conversions, a conversion from IANA system to Windows system may be necessary if a conversion to DateTimeOffset or an access to Offset is requested by the user. Unicode CLDR mapping is used for this conversion. Please bear in mind that Windows time zone database do not provide precise historical data, so you may end up with inaccurate DateTimeOffset values for past values. It is recommended that you use driver level temporal types to avoid these inaccuracies.

Logging

The driver accepts a logger that implements ILogger interface. To pass a ILogger to this driver:

IDriver driver = GraphDatabase.Driver("neo4j://localhost:7687", AuthTokens.Basic("username", "pasSW0rd"), o => o.WithLogger(logger));

In this ILogger interface, each logging method takes a message format string and message arguments as input. The full log messages can be restored using string.format(message_format, message_argument).

An example of implementing ILogger with Microsoft.Extensions.Logging:

public class DriverLogger : ILogger
{
    private readonly Microsoft.Extensions.Logging.ILogger _delegator;
    public DriverLogger(Microsoft.Extensions.Logging.ILogger delegator)
    {
       _delegator = delegator;
    }
    public void Error(Exception cause, string format, params object[] args)
    {
        _delegator.LogError(default(EventId), cause, format, args);
    }
    ...
}

Migrating from 1.7 to 4.0

This section is for users who would like to migrate their 1.7 driver to 4.0. The following sections serve as a quick look at what have been added and/or changed in 4.0 .NET driver. For more information, also checkout our Driver Migration Guide.

What's New

  • Upcoming version is now named as 4.0.0 instead of 2.0.0 to better align with server versions.
  • Bolt V4.0 is implemented in the 4.0.0 driver.
  • Reactive API is available under namespace Neo4j.Driver.Reactive when using together with Neo4j 4.0 databases.
  • Multi-databases support is added. Database can be selected for each session on creation with SessionConfig#ForDatabase.
  • A new feature detection method IDriver#SupportsMultiDbAsync is added for querying if the remote database supports multi-databases.
  • A new IDriver#VerifyConnectivityAsync method is introduced for verify the availability of remote DBMS.

Breaking Changes

  • Encrypted is turned off by default. When encryption is explicitly enabled, the default trust mode is to trust the certificates that are trusted by underlying operating system, and hostname verification is enforced by default.
  • v1 is removed from drivers' package name. All public APIs are under the namespace Neo4j.Driver instead of the old Neo4j.Driver.V1.
  • The Neo4j.Driver package contains only the asynchronous API. Synchronous session API has been moved to the namespace Neo4j.Driver.Simple.
  • A new neo4j scheme is added and designed to work with all possible 4.0 server deployments. bolt scheme is still available for explicit direct connections with a single instance and/or a single member in a cluster. For 3.x servers, neo4j replaces bolt+routing.
  • Asynchronous methods have been extracted out and put in interfaces prefixed with IAsync, whereas synchronous methods are kept under the old interface but live in package Neo4j.Driver.Simple. This change ensures that blocking and no-blocking APIs can never be mixed together.
  • IDriver#Session methods now make use of a session option builder rather than method arguments.
  • Bookmark has changed from a string and/or a list of strings to a Bookmark object.
  • ITransaction#Success is replaced with ITransaction#Commit. However unlike ITransaction#Success which only marks the transaction to be successful and then waits for ITransaction#Dispose to actually perform the real commit, ITransaction#Commit commits the transaction immediately. Similarly, ITransaction#Failure is replaced with ITransaction#Rollback. A transaction in 4.0 can only be committed OR rolled back once. If a transaction is not committed explicitly using ITransaction#Commit, ITransaction#Dispose will roll back the transaction.
  • Statement has been renamed to Query. IStatementResult has been simplified to IResult. Similarly, IStatementResultCursor has been renamed to IResultCursor.
  • A result can only be consumed once. A result is consumed if either the query result has been discarded by invoking IResult#Consume and/or the outer scope where the result is created, such as a transaction or a session, has been closed. Attempts to access consumed results will be responded with a ResultConsumedException.
  • LoadBalancingStrategy is removed from Config class and the drivers always default to LeastConnectedStrategy.
  • The IDriverLogger has been renamed to ILogger.
  • TrustStrategy is replaced with TrustManager.

For Driver Developers

This section targets at people who would like to compile the source code on their own machines for the purpose of, for example, contributing a PR to this repository. Before contributing to this project, please take a few minutes and read our Contributing Criteria.

Snapshots

Snapshot builds are available at our MyGet feed, add the feed to your Nuget Sources to access snapshot artifacts.

Testing

Tests require the latest Testkit 4.3, Python3 and Docker.

Testkit is needed to be cloned and configured to run against the Dotnet Driver. Use the following steps to configure Testkit.

  1. Clone the Testkit repository
git clone https://github.com/neo4j-drivers/testkit.git
  1. Under the Testkit folder, install the requirements.
pip3 install -r requirements.txt
  1. Define some enviroment variables to configure Testkit
export TEST_DRIVER_NAME=dotnet
export TEST_DRIVER_REPO=<path for the root folder of driver repository>

To run test against against some Neo4j version:

python3 main.py

More details about how to use Teskit could be found on its repository

Building the Source Code on Windows

Visual Studio Version

The driver is written in C# 7 so will require Visual Studio 2017.

Integration Tests

The integration tests use boltkit to download and install a database instance on your local machine. They can fail for three main reasons:

  1. Python.exe and Python scripts folder is not installed and added in the system PATH variable
  2. The tests aren't run as Administrator (you'll need to run Visual Studio as administrator)
  3. You have an instance of Neo4j already installed / running on your local machine.

The database installation uses boltkit neoctrl-install command to install the database. It is possible to run the integration tests against a specific version by setting environment variable NEOCTRL_ARGS.

Run tests

The simplest way to run all tests from command line is to run runTests.ps1 powershell script:

.\Neo4j.Driver\runTests.ps1

Any parameter to this powershell script will be used to reset environment variable NEOCTRL_ARGS:

.\Neo4j.Driver\runTests.ps1 -e 4.0.0

Building the Source Code on MacOS and/or Linux

The driver targets at .NET Standard 2.0. and .NET 5.0 As a result, it can be compiled and run on linux machines after installing for example .NET Core 2.0 library. As for IDE, we recommend Rider for daily development. The integration tests require boltkit to be installed and accessible via command line. If any problem to start a Neo4j Server on your machine, you can start the test Bolt Server yourself at localhost:7687 and then set environment variable DOTNET_DRIVER_USING_LOCAL_SERVER=true

More Repositories

1

neo4j

Graphs for Everyone
Java
13,266
star
2

NaLLM

Repository for the NaLLM project
TypeScript
1,253
star
3

neo4j-python-driver

Neo4j Bolt driver for Python
Python
898
star
4

neo4j-javascript-driver

Neo4j Bolt driver for JavaScript
JavaScript
853
star
5

neo4j-browser

Neo4j Browser is the general purpose user interface for working with Neo4j. Query, visualize, administrate and monitor the database.
TypeScript
690
star
6

graph-data-science

Source code for the Neo4j Graph Data Science library of graph algorithms.
Java
629
star
7

graphql

A GraphQL to Cypher query execution layer for Neo4j and JavaScript GraphQL implementations.
TypeScript
504
star
8

neo4j-go-driver

Neo4j Bolt Driver for Go
Go
494
star
9

docker-neo4j

Docker Images for the Neo4j Graph Database
Shell
333
star
10

neo4j-ogm

Java Object-Graph Mapping Library for Neo4j
Java
332
star
11

neo4j-java-driver

Neo4j Bolt driver for Java
Java
329
star
12

neo4j-spark-connector

Neo4j Connector for Apache Spark, which provides bi-directional read/write access to Neo4j from Spark, using the Spark DataSource APIs
Scala
313
star
13

cypher-dsl

A Java DSL (Builder) for the Cypher Query Language
Java
194
star
14

graph-data-science-client

A Python client for the Neo4j Graph Data Science (GDS) library
Python
191
star
15

neo4j-graphrag-python

Neo4j GraphRAG for Python
Python
172
star
16

neo4j-jdbc

Official Neo4j JDBC Driver
Java
135
star
17

neo4j-documentation

Scala
103
star
18

apoc

Java
94
star
19

cypher-shell

Cypher Shell has moved to https://github.com/neo4j/neo4j
Java
89
star
20

trillion-graph

A scale demo of Neo4j Fabric spanning up to 1129 machines/shards running a 100TB (LDBC) dataset with 1.2tn nodes and relationships.
Java
89
star
21

docker-neo4j-publish

Shell
83
star
22

sdn-rx

Nextgen Spring Data module for Neo4j supporting (not only) reactive data access and immutable support
Java
65
star
23

helm-charts

Go
59
star
24

cypher-builder

A library for building Cypher queries for Neo4j programmatically.
TypeScript
50
star
25

cypher-editor

Codemirror editor for Cypher, with syntax awareness and auto-completion
JavaScript
42
star
26

neo4j-java-driver-spring-boot-starter

Automatic configuration of Neo4j's Java Driver for Spring Boot applications
Java
33
star
27

cypher-language-support

Neo4j's Cypher Language support
TypeScript
31
star
28

neo4j-example-auth-plugins

Example authentication and authorization plugins for Neo4j
Java
17
star
29

neo4j-ogm-quarkus

Quarkus extension to that allows proper usage of Neo4j-OGM inside Quarkus.
Java
13
star
30

neo4j-python-driver-rust-ext

Optional Rust Extensions to Speed Up the Python Driver
Python
13
star
31

graphql-tracker-temp

This is a temporary repository for documentation and tracking issues for the @neo4j/graphql package until that repo is made public
12
star
32

docs-cypher

Neo4j Cypher Documentation
JavaScript
12
star
33

graph-schema-introspector

This is a Proof of concept (PoC) for a Neo4j schema introspector that produces output in JSON format validating against graph-schema-json-js-utils.
Java
11
star
34

docs-drivers

Neo4j Drivers Documentation
Python
10
star
35

windows-wrapper

A service wrapper for windows
Java
9
star
36

docs-bolt

Neo4j Bolt Protocol Documentation
JavaScript
7
star
37

neo4j.github.com

Web published resources
HTML
7
star
38

dappr

Distributed Approximate Personalised PageRank
Jupyter Notebook
6
star
39

docs-operations

Neo4j Operations documentation
JavaScript
6
star
40

docs-getting-started

JavaScript
6
star
41

jsr311-api

Forked from revision 612
Java
6
star
42

docs-graphql

GraphQL docs
JavaScript
5
star
43

doctools

Perl
5
star
44

graph-schema-json-js-utils

Utility library to work with the Graph Schema JSON representation
TypeScript
5
star
45

docs-aura

Jupyter Notebook
5
star
46

kafka-connector-workshop

TypeScript
4
star
47

neo4j-kafka-connector

Neo4j Kafka Connector
Kotlin
4
star
48

graphql-toolbox

TypeScript
4
star
49

github-action-traceability

TypeScript
4
star
50

docs-status-codes

Documentation for Neo4j status codes
JavaScript
4
star
51

parents

Neo4j Build Configuration
4
star
52

neo4j-aws-terraform

HCL
3
star
53

docs-http-api

Documentation for Neo4j HTTP API
JavaScript
3
star
54

jbang-catalog

JBang catalog
Java
2
star
55

import-spec

Java
2
star
56

docs-maven-plugin

Java
2
star
57

ease-maven-plugin

Java
2
star
58

license-maven-plugin

Fork of http://code.google.com/p/maven-license-plugin/
Java
2
star
59

maven-skin

Neo4j Maven Skin
Java
2
star
60

docs-bloom

JavaScript
1
star
61

docs-data-importer

JavaScript
1
star
62

azure-neo4j

Azure topology files
Shell
1
star
63

clirr-maven-plugin

Java
1
star
64

neo4jtester

neo4j tester
Go
1
star
65

docs-genai-tutorials

Python
1
star
66

docs-ops-manager

JavaScript
1
star