Releases: neo4j/neo4j-dotnet-driver
5.10.0
No changes.
5.9.0
⭐ New Features
- Support for bolt protocol 5.3 which adds
bolt_agentmetadata so that the server knows which driver is connecting (#706). - Re-authentication (in preview) (#689)
Allows for handling expiring authentication (backwards compatible) as well as session scoped authentication (requires neo4j server version 5.5+).
We are actively looking for feedback: #705
📚 Docs
Mention performance impact of notification filtering (#703).
5.8.0
⭐ New Features
- The ExecuteQuery API has now been moved out of preview. This provides a much simpler way to execute queries directly at the driver level, with sessions, transactions and bookmarks handled automatically.
Examples
var queryOp = await driver
.ExecutableQuery("MATCH (person:Person) RETURN person")
.ExecuteAsync();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, for example:
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();With this method, the return type will be EagerResult<IReadonlyList<string>>. Multiple .WithMap and .WithFilter calls may be chained together. Note that filtering is performed locally here so it should not be used in place of doing filtering on the server.
There is also a .WithReduce method, to be used as follows:
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();This will result in an EagerResult<int>, with the Result property containing the sum of all the ages.
Custom processing of the record stream can be done by using the .WithStreamProcessor method:
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 age = record["person"].As<INode>()["age"].As<double>();
total += age;
count++;
}
return total / count;
})
.ExecuteAsync();Here we simply supply a delegate, which will be called, passing a parameter of type IAsyncEnumerable<IRecord>. The value returned from this delegate will be an EagerResult<double>, with the Result property containing the average age.
Parameters can also be specified using the fluent interface, as follows.
var paramQuery = await driver
.ExecutableQuery("MATCH (p:Person) WHERE p.name = $name RETURN p")
.WithParameters(new { name = "Tom Hanks" })
.WithMap(r => r["p"].As<INode>()["name"].As<string>())
.ExecuteAsync();5.7.0
🔬 Experimental/Preview changes
- the
Neo4j.Driver.Experimentalnamespace has been renamed toNeo4j.Driver.Preview. This will be a compile-time breaking change for any code using this namespace. No functionality has been changed.
⭐ New Features
- ⭐ Introduce
IDriver.TryVerifyConnectivityAsync
⭐ Notifications Updates #691
Introduce better notifications, and configuration(Docs).
NotificationSeverity
Introduce NotificationSeverity enum represents to represent a notification's severity level.
Severities:
WarningInformationUnknown
NotificationCategory
Introduce NotificationCategory enum represents to represent a notification's category.
Categories:
HintUnrecognizedUnsupportedPerformanceDeprecationGenericUnknown
Notification
The INotification interface extended with 4 new properties:
NotificationSeverity SeverityLevelstring RawSeverityLevelNotificationCategory Categorystring RawCategory
The Raw prefixed properties return an unparsed string representation returned by the server.
In case of an unrecognised values, both SeverityLevel and Category will be Unknown.
This may happen if a new value is introduced in a future server version and a previous driver version does not support it.
Additionally, Unknown may be returned when driver communicates with a server version that does not supply these values.
Deprecation ⚠️
The Severity property has been deprecated in favour of the RawSeverityLevel property.
NotificationConfig
Introduce INotificationConfig type has been introduced to allow notification preferences management.
By default, the server determines what notifications are provided to the driver.
However, user can set a minimum severity level and/or a set of disabled notification categories to manage its expectations.
This feature is only supported on Bolt protocol version 5.2(Introduced in server 5.7) and above.
Both the Config and the SessionConfig support this new configuration, configured with builders:
ConfigBuilder.WithNotificationsDisabled5.7 API DocConfigBuilder.WithNotifications5.7 API DocSessionConfigBuilder.WithNotificationsDisabled5.7 API DocSessionConfigBuilder.WithNotifications5.7 API Doc
Introduce Severity(API Docs) & Category(API Docs) enums for configuration.
Notification Configuration Hierarchy
Servers will assess which notifications to emit based on a hierarchy, using the most recently declared values.
using var driver = GraphDatabase.Driver(Neo4jUrl, AuthToken, cb => cb.WithNotificationsDisabled());
using var session = driver.AsyncSession();
...
var summary = await cursor.ConsumeAsync();
// No notifications should be emitted.
// This is useful for helping the server optimize operations as the server doesn't need to assess for any notifications.
// Notifications are not sent over the wire too meaning less data!
Debug.Assert(summary.Notifications.Count() == 0); Severity configuration sets the minimum level of a notification, while category confugration is used to disable a category.
using var driver = GraphDatabase.Driver(Neo4jUrl, AuthToken, cb => cb.WithNotifications(Severity.Warning, null));
using var session = driver.AsyncSession(scb => scb.WithNotifications(null, new []{Category.Performance}));
...
var summary = await cursor.ConsumeAsync();
// no Information or performance notifications emitted.
Debug.Assert(summary.Notifications.Count(x =>
x.NotificationCategory == NotificationCategory.Performance ||
x.NotificationSeverity == NotificationSeverity.Information) == 0); if you require to enable a previously disabled categories for a session you can emit it from disabledCategories parameter.
using var driver = GraphDatabase.Driver(Neo4jUrl, AuthToken, cb => cb.WithNotifications(null, new []{Category.Performance}));
using var session = driver.AsyncSession(scb => scb.WithNotifications(null, new Category[]{}));
...
var summary = await cursor.ConsumeAsync();
// Notifications can contain anything again!Bolt
This update includes support for both 5.1 and 5.2 versions. The latter is required for the full support of the new notification updates.
5.6.0
No changes.
5.5.0
5.4.0
🔧 Fixes
- Add documentation for SessionConfigBuilder.WithDatabase and SessionConfig.Database
- Exclude test code in snyk code analysis
- TestKit backend: exclude txMeta from Cypher types
- Add new exception types and change to explicitly identifying fast fail errors
5.3.0
🔬 Experimental bookmark manager changes:
- Remove database notions from bookmark manager.
- Fix Bookmark manager references outside of Neo4j.Driver.Experimental namespace.
- When replacing LastBookmark with LastBookmarks we accidentally removed the old property, not following the planned deprecation policy. It is now restored and marked as obsolete, and due for removal in 6.0 of the driver.
- Simplify creation of bookmark manager with default config.
5.2.0
What's Changed
🔬 Experimental change
- Fixed an issue bookmark manager experimental classes: correctly exposing
WithBookmarkManagerto use bookmark managers on session configuration(#654).
Full Changelog: 5.1.0...5.2.0