HotChocolate has a data integration for Neo4J. With this integration, you can translate paging, filtering, sorting, and projections, directly into native cypher queries.
You can find an example project in HotChocolate Examples
Get Started
To use the Neo4J integration, you need to install the package HotChocolate.Data.Neo4J
.
dotnet add package HotChocolate.Data.Neo4J
HotChocolate.*
packages need to have the same version.Neo4JExecutable
The whole integration builds around IExecutable<T>
.
The execution engine picks up the IExecutable
and executes it efficiently.
[UseNeo4JDatabase("neo4j")][UsePaging][UseProjection][UseSorting][UseFiltering]public IExecutable<Person> GetPersons([ScopedService] IAsyncSession session) => new Neo4JExecutable<Person>(session);
Filtering
To use Neo4J filtering you need to register the convention on the schema builder:
services .AddGraphQLServer() .AddQueryType<Query>() .AddNeo4JFiltering();
To use Neo4J filtering alongside with
IQueryable
/IEnumerable
, you have to register the Neo4J convention under a different scope. You can specify the scope on the schema builder by executingAddNeo4JFiltering("yourScope")
. You then have to specify this scope on each method you use Neo4J filtering:[UseFiltering(Scope = "yourScope")]
orUseFiltering(scope = "yourScope")
Your filters are now converted to cypher and applied to the executable.
GraphQL Query:
query GetPersons { persons( where: { name: { eq: "Yorker Shorton" } addresses: { some: { street: { eq: "04 Leroy Trail" } } } } ) { name addresses { street city } }}
Cypher Query
MATCH (person:Person)WHERE person.name = 'Yorker Shorton" ANDRETURN person {.name}
Sorting
To use Neo4J sorting you need to register the convention on the schema builder:
services .AddGraphQLServer() .AddQueryType<Query>() .AddNeo4JSorting();
To use Neo4J Sorting alongside with
IQueryable
/IEnumerable
, you have to register the Neo4J convention under a different scope. You can specify the scope on the schema builder by executingAddNeo4JSorting("yourScope")
. You then have to specify this scope on each method you use Neo4J Sorting:[UseSorting(Scope = "yourScope")]
orUseSorting(scope = "yourScope")
Your sorting is now converted to cypher and applied to the executable.
GraphQL Query:
query GetPersons { persons(order: [{ name: ASC }]) { name addresses { street city } }}
Cypher Query
MATCH (person:Person)WHERE person.name = 'Yorker Shorton" ANDRETURN person {.name}
Projections
To use Neo4J projections you need to register the convention on the schema builder:
services .AddGraphQLServer() .AddQueryType<Query>() .AddNeo4JProjections();
To use Neo4J Projections alongside with
IQueryable
/IEnumerable
, you have to register the Neo4J convention under a different scope. You can specify the scope on the schema builder by executingAddNeo4JProjections("yourScope")
. You then have to specify this scope on each method you use Neo4J Projections:[UseProjections(Scope = "yourScope")]
orUseProjections(scope = "yourScope")
GraphQL Query:
query GetPersons { persons { name addresses { city } }}
Cypher Query
MATCH (person:Person)WHERE person.name = 'Yorker Shorton" ANDRETURN person {.name}
Paging
In order to use pagination with Neo4J, we have to register the Neo4J specific pagination providers.
services .AddGraphQLServer() .AddNeo4JPagingProviders();
Learn more about pagination providers
Cursor Pagination
To use cursor based pagination annotate you resolver with [UseNeo4JPaging]
or .UseNeo4JPaging()
[UseNeo4JDatabase("neo4j")][UsePaging][UseProjection]public IExecutable<Person> GetPersons([ScopedService] IAsyncSession session) => new Neo4JExecutable<Person>(session);
You can then execute queries like the following one:
query GetPersons { persons(first: 50, after: "OTk=") { nodes { name addresses { city } } pageInfo { endCursor hasNextPage hasPreviousPage startCursor } }}
Offset Pagination
To use cursor based pagination annotate you resolver with [UseNeo4JPaging]
or .UseNeo4JPaging()
[UseNeo4JDatabase("neo4j")][UseOffsetPaging][UseProjection]public IExecutable<Person> GetPersons([ScopedService] IAsyncSession session) => new Neo4JExecutable<Person>(session);
You can then execute queries like the following one:
query GetPersons { persons(skip: 50, take: 50) { items { name addresses { city } } pageInfo { hasNextPage hasPreviousPage } }}