Data types and mapping to Cypher types
The tables in this section show the mapping between Cypher data types and .NET types.
Core types
| Cypher type | Driver type | 
|---|---|
  | 
|
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
Temporal types
The driver provides a set of temporal data types compliant with ISO-8601 and Cypher.
Sub-second values are measured to nanosecond precision.
Time zone names adhere to the IANA system, rather than the Windows system.
Inbound conversion is carried out using Extended Windows-Olson zid mapping as defined by Unicode CLDR.
| Cypher type | Driver type | 
|---|---|
  | 
|
  | 
|
  | 
|
  | 
|
  | 
|
  | 
// Define a date, with timezone, and use it to set a relationship property
var friendsSince = new ZonedDateTime(new DateTime(2016, 12, 16, 13, 59, 59, 999), "Europe/Stockholm");
var result = await driver.ExecutableQuery(@"
    MERGE (a:Person {name: $name})
    MERGE (b:Person {name: $friend})
    MERGE (a)-[friendship:KNOWS {since: $friendsSince}]->(b)
    RETURN friendship.since AS date
")
    .WithParameters(new { name = "Astrid", friend = "Sara", friendsSince = friendsSince })
    .WithConfig(new QueryConfig(database: "<database-name>"))
    .ExecuteAsync();
Console.WriteLine(result.Result[0].Get<ZonedDateTime>("date"));
// 2016-12-16T13:59:59.999000000[Europe/Stockholm]
Spatial types
Cypher supports spatial values (points), and Neo4j can store these point values as properties on nodes and relationships.
The attribute SRID (short for Spatial Reference Identifier) is a number identifying the coordinate system the spatial type is to be interpreted in.
You can think of it as a unique identifier for each spatial type.
| Cypher type | Driver type | SRID | 
|---|---|---|
  | 
7203  | 
|
  | 
4326  | 
|
  | 
9157  | 
|
  | 
4979  | 
Point value from the databasevar result = await driver.ExecutableQuery("RETURN point({x: 2.3, y: 4.5, z: 2}) AS point")
    .WithConfig(new QueryConfig(database: "<database-name>"))
    .ExecuteAsync();
Console.WriteLine(result.Result[0].Get<Point>("point"));
// Point{srId=9157, x=2.3, y=4.5, z=2}
Point value and use it as property valuevar location = new Point(4326, 67.28775180193841, 17.734163823312397);  // 4326 = 2D geodetic point
var result = await driver.ExecutableQuery("CREATE (p:PlaceOfInterest {location: $location}) RETURN p")
    .WithParameters(new { location = location })
    .WithConfig(new QueryConfig(database: "<database-name>"))
    .ExecuteAsync();
Console.WriteLine(result.Result[0].Get<INode>("p").Get<Point>("location"));
// Point{srId=4326, x=67.28775180193841, y=17.734163823312397}
Graph types
Graph types are only passed as results and may not be used as parameters.
| Cypher Type | Driver type | 
|---|---|
  | 
|
  | 
|
  | 
INode
Represents a node in a graph.
| Property/Method | Return | 
|---|---|
  | 
Node labels, as a list.  | 
  | 
Node properties, as a map.  | 
  | 
Value for the given property, casted to   | 
  | 
String identifier for the node.
This should be used with care, as no guarantees are given about the mapping between id values and elements outside the scope of a single transaction. In other words, using an   | 
var result = await driver.ExecutableQuery("MERGE (p:Person:Troublemaker {name: $name, age: $age}) RETURN p")
    .WithParameters(new { name = "Carla", age = 59 })
    .WithConfig(new QueryConfig(database: "<database-name>"))
    .ExecuteAsync();
var node = result.Result[0].Get<INode>("p");
Console.WriteLine("Labels: {0}", string.Join(", ", node.Labels));
Console.WriteLine("Properties: {0}", string.Join(", ", node.Properties));
Console.WriteLine("Name property: {0}", node.Get<string>("name"));
/*
Labels: Person, Troublemaker
Properties: [name, Carla], [age, 59]
Name property: Carla
*/
For full documentation, see API documentation → INode.
IRelationship
Represents a relationship in a graph.
| Property/Method | Return | 
|---|---|
  | 
Relationship type.  | 
  | 
Relationship properties, as a map.  | 
  | 
Value for the given property, casted to   | 
  | 
  | 
  | 
  | 
  | 
String identifier for the relationship.
This should be used with care, as no guarantees are given about the mapping between id values and elements outside the scope of a single transaction. In other words, using an   | 
var result = await driver.ExecutableQuery(@"
    MERGE (p:Person {name: $name})
    MERGE (friend:Person {name: $friendName})
    MERGE (p)-[r:KNOWS {status: $status, since: date()}]->(friend)
    RETURN r AS friendship
    ")
    .WithParameters(new { name = "Alice", friendName = "Bob", status = "BFF" })
    .WithConfig(new QueryConfig(database: "<database-name>"))
    .ExecuteAsync();
var relationship = result.Result[0].Get<IRelationship>("friendship");
Console.WriteLine($"Type: {relationship.Type}");
Console.WriteLine("Properties: {0}", string.Join(", ", relationship.Properties));
Console.WriteLine("Status property: {0}", relationship.Get<string>("status"));
/*
Type: KNOWS
Properties: [since, 2024-12-22], [status, BFF]
Status property: BFF
*/
For full documentation, see API documentation → IRelationship.
IPath
Represents a path in a graph.
using Neo4j.Driver;
const string dbUri = "<database-uri>";
const string dbUser = "<username>";
const string dbPassword = "<password>";
await using var driver = GraphDatabase.Driver(dbUri, AuthTokens.Basic(dbUser, dbPassword));
await driver.VerifyConnectivityAsync();
// Create some :Person nodes linked by :KNOWS relationships
await addFriend(driver, "Alice", "BFF", "Bob");
await addFriend(driver, "Bob", "Fiends", "Sofia");
await addFriend(driver, "Sofia", "Acquaintances", "Alice");
// Follow :KNOWS relationships outgoing from Alice three times, return as path
var result = await driver.ExecutableQuery(@"
    MATCH path=(:Person {name: $name})-[:KNOWS*3]->(:Person)
    RETURN path AS friendshipChain
    ")
    .WithParameters(new { name = "Alice" })
    .WithConfig(new QueryConfig(database: "<database-name>"))
    .ExecuteAsync();
// Extract path from result
var path = result.Result[0].Get<IPath>("friendshipChain");
Console.WriteLine("-- Path breakdown --");
for (var i=0; i<path.Relationships.Count; i++) {
    Console.WriteLine("{0} knows {1} ({2}).",
        path.Nodes[i].Get<string>("name"),
        path.Nodes[i+1].Get<string>("name"),
        path.Relationships[i].Get<string>("status")
    );
}
/*
-- Path breakdown --
Alice knows Bob (BFF).
Bob knows Sofia (Fiends).
Sofia knows Sofia (Acquaintances).
*/
async Task addFriend(IDriver driver, string name, string status, string friendName) {
    await driver.ExecutableQuery(@"
        MERGE (p:Person {name: $name})
        MERGE (friend:Person {name: $friendName})
        MERGE (p)-[r:KNOWS {status: $status, since: date()}]->(friend)
        ")
        .WithParameters(new { name = name, status = status, friendName = friendName })
        .WithConfig(new QueryConfig(database: "<database-name>"))
        .ExecuteAsync();
}
For full documentation, see API documentation → IPath.
Glossary
- LTS
 - 
A Long Term Support release is one guaranteed to be supported for a number of years. Neo4j 4.4 is LTS, and Neo4j 5 will also have an LTS version.
 - Aura
 - 
Aura is Neo4j’s fully managed cloud service. It comes with both free and paid plans.
 - Cypher
 - 
Cypher is Neo4j’s graph query language that lets you retrieve data from the database. It is like SQL, but for graphs.
 - APOC
 - 
Awesome Procedures On Cypher (APOC) is a library of (many) functions that can not be easily expressed in Cypher itself.
 - Bolt
 - 
Bolt is the protocol used for interaction between Neo4j instances and drivers. It listens on port 7687 by default.
 - ACID
 - 
Atomicity, Consistency, Isolation, Durability (ACID) are properties guaranteeing that database transactions are processed reliably. An ACID-compliant DBMS ensures that the data in the database remains accurate and consistent despite failures.
 - eventual consistency
 - 
A database is eventually consistent if it provides the guarantee that all cluster members will, at some point in time, store the latest version of the data.
 - causal consistency
 - 
A database is causally consistent if read and write queries are seen by every member of the cluster in the same order. This is stronger than eventual consistency.
 - NULL
 - 
The null marker is not a type but a placeholder for absence of value. For more information, see Cypher → Working with
null. - transaction
 - 
A transaction is a unit of work that is either committed in its entirety or rolled back on failure. An example is a bank transfer: it involves multiple steps, but they must all succeed or be reverted, to avoid money being subtracted from one account but not added to the other.
 - backpressure
 - 
Backpressure is a force opposing the flow of data. It ensures that the client is not being overwhelmed by data faster than it can handle.
 - transaction function
 - 
A transaction function is a callback executed by an
.ExecuteReadAsync()or.ExecuteWriteAsync()call. The driver automatically re-executes the callback in case of server failure. - IDriver
 - 
A
IDriverobject holds the details required to establish connections with a Neo4j database.