From a49bc98155f7cbba065e27b79a901eaac54966b8 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Wed, 29 Oct 2025 17:24:02 +0000 Subject: [PATCH 1/3] WIP migration guide for v3 --- .changeset/easy-horses-repeat.md | 2 +- docs/modules/ROOT/content-nav.adoc | 1 + .../modules/ROOT/pages/migration-guide-2.adoc | 2 +- .../modules/ROOT/pages/migration-guide-3.adoc | 293 ++++++++++++++++++ 4 files changed, 296 insertions(+), 2 deletions(-) create mode 100644 docs/modules/ROOT/pages/migration-guide-3.adoc diff --git a/.changeset/easy-horses-repeat.md b/.changeset/easy-horses-repeat.md index 267ae183..4f2a828d 100644 --- a/.changeset/easy-horses-repeat.md +++ b/.changeset/easy-horses-repeat.md @@ -14,7 +14,7 @@ const { cypher, params } = matchQuery.build({ _Before_ -```js +```cypher MATCH (this1:Movie:Film) ``` diff --git a/docs/modules/ROOT/content-nav.adoc b/docs/modules/ROOT/content-nav.adoc index 14df508d..f2e7c152 100644 --- a/docs/modules/ROOT/content-nav.adoc +++ b/docs/modules/ROOT/content-nav.adoc @@ -45,5 +45,6 @@ ** xref:how-to/define-cypher-version.adoc[] * xref:compatibility.adoc[] * xref:migration-guide-2.adoc[] +* xref:migration-guide-3.adoc[] * link:https://github.com/neo4j/cypher-builder/tree/main/examples[Examples] * link:https://neo4j.github.io/cypher-builder/reference/[Reference] diff --git a/docs/modules/ROOT/pages/migration-guide-2.adoc b/docs/modules/ROOT/pages/migration-guide-2.adoc index eccec4dc..533aadde 100644 --- a/docs/modules/ROOT/pages/migration-guide-2.adoc +++ b/docs/modules/ROOT/pages/migration-guide-2.adoc @@ -1,4 +1,4 @@ -[[migration]] +[[migration-2]] :description: This page describes how to migrate to version 2.x = Migration to Cypher Builder 2 diff --git a/docs/modules/ROOT/pages/migration-guide-3.adoc b/docs/modules/ROOT/pages/migration-guide-3.adoc new file mode 100644 index 00000000..87f2550f --- /dev/null +++ b/docs/modules/ROOT/pages/migration-guide-3.adoc @@ -0,0 +1,293 @@ +[[migration]] +:description: This page describes how to migrate to version 3.x from version 2 += Migration to Cypher Builder 3 + +Cypher Builder 3 targets Cypher 5 and 25, dropping support for Cypher 4. If you need to support Cypher 4, stay with Cypher Builder 2.x, otherwise, migrate to version 3. + +== Compatibility changes + +=== Minimum node engine changed to 20.0.0 + +Node.js 16 is no longer supported. Update to version 20.0.0 or above. + +=== Cypher 4 no longer supported + +Cypher 4, and Neo4j 4 databases are no longer supported. Cypher Builder targets Cypher 5 and 25 only. + + + + +== Remove support for apoc + +No apoc functions or procedures are supported in Cypher Builder 3. The following are no longer available: + +- `apoc.util.validate` +- `apoc.util.validatePredicate` +- `apoc.date.convertFormat` +- `apoc.cypher.runFirstColumnMany` +- `apoc.cypher.runFirstColumnSingle` + +To use apoc methods, create a xref:how-to/customize-cypher.adoc#_custom_functions_and_procedures[custom function or procedure]. For example: + +[source, Javascript] +---- +function validate( + predicate: Predicate, + message: string, + params: List | Literal | Map +): Cypher.VoidCypherProcedure { + return new Cypher.VoidCypherProcedure( + "apoc.util.validate", + [predicate, new Literal(message), params] + ); +} +---- + +[source, Javascript] +---- +function validatePredicate(predicate: Predicate, message: string): CypherFunction { + return new CypherFunction(" + apoc.util.validatePredicate", + [predicate, new Literal(message), new Literal([0])] + ); +} +---- + +== Cypher 4 only features + +The following features have been either removed or deprecated in Cypher 5, and are no longer available in Cypher Builder 3 + + +=== Remove functions deprecated in Cypher 5 + +- `distance` in favor of `point.distance` +- `id` in favor of `elementId` + +=== Remove support for patterns in size + +_No longer supported_ + +[source, javascript] +---- +Cypher.size(new Cypher.Pattern(node)); +---- + +[source, Cypher] +---- +size((this0)); +---- + +Instead, use `new Cypher.Count`: + +[source, javascript] +---- +new Cypher.Count(new Cypher.Pattern(node)); +---- + +[source, Cypher] +---- +COUNT { + (this0) +} +---- + + +=== Remove `labelOperator` + +Removed option `labelOperator`. All labels now use operator `&` + + +_No longer supported_ + +[source, javascript] +---- +const { cypher, params } = matchQuery.build({ + labelOperator: "&", +}); +---- + + +_Before_ + +[source, Cypher] +---- +MATCH (this1:Movie:Film) +---- + +_After_ + +[source, Cypher] +---- +MATCH (this1:Movie&Film) +---- + + +=== Remove `.importWith` from `Call` + +Remove `.importWith` from `Call` clauses in favor of constructor options + +_No longer supported_ + +[source, Javascript] +---- +const clause = new Cypher.Call(nestedClause).importWith(movieNode, actorNode); +---- + +[source, Cypher] +---- +CALL { + WITH var0, var1 + // Nested clause +} +---- + +_After_ + +[source, Javascript] +---- +const clause = new Cypher.Call(nestedClause, [movieNode, actorNode]); +---- + +[source, Cypher] +---- +CALL (var0, var1){ + // Nested clause +} +---- + + +== ListComprehension + +The methods for `ListComprehension` have been changed to improve consistency with other elements of Cypher Builder. + + +=== Remove second parameter of constructor +Remove second parameter of `ListComprehension` constructor in favor of `.in` + +Before: +[source, javascript] +---- +new Cypher.ListComprehension(variable, new Cypher.Literal([1, 2])); +---- + +After: +[source, javascript] +---- +new Cypher.ListComprehension(variable).in(new Cypher.Literal([1, 2])); +---- + +In both cases, the same comprehension will be generated: + +```cypher +[var0 IN [1, 2]] +``` + +=== ListComprehension `.in` method no longer throws if called twice. + +ListComprehension `.in` method no longer throws if called twice. It will instead override the expression + +Before, it will throw: +[source, javascript] +---- +new Cypher.ListComprehension(variable).in(new Cypher.Literal([1, 2])).in(new Cypher.Literal([1])) +---- + +After, this is valid: +[source, javascript] +---- +new Cypher.ListComprehension(variable).in(new Cypher.Literal([1, 2])).in(new Cypher.Literal([1])) +---- + +Will generate the following Cypher: + +[source, cypher] +---- +[var0 IN [1]] +---- + +Note that the same Cypher is generated if we omit the first `.in`: + +After, this is valid: +[source, javascript] +---- +new Cypher.ListComprehension(variable).in(new Cypher.Literal([1])) +---- + + +== Foreach + +The methods for `Foreach` have been changed to improve consistency with other elements of Cypher Builder. + +=== Remove extra parameters in `Cypher.Foreach` constructor +Remove extra parameters in `Cypher.Foreach` constructor in favor of methods `in` and `do`. + +For example, to create the following Cypher: + +[source, Cypher] +---- +FOREACH (var0 IN [1, 2, 3] | + CREATE (this1:Movie) + SET + this1.id = var0 + ) +---- + +_before_ + +[source, javascript] +---- +const list = new Cypher.Literal([1, 2, 3]); +const variable = new Cypher.Variable(); + +const movieNode = new Cypher.Node(); +const createMovie = new Cypher.Create(new Cypher.Pattern(movieNode, { labels: ["Movie"] })).set([ + movieNode.property("id"), + variable, +]); + +const foreachClause = new Cypher.Foreach(variable, list, createMovie); +---- + +_after_ + +[source, javascript] +---- +const list = new Cypher.Literal([1, 2, 3]); +const variable = new Cypher.Variable(); + +const movieNode = new Cypher.Node(); +const createMovie = new Cypher.Create(new Cypher.Pattern(movieNode, { labels: ["Movie"] })).set([ + movieNode.property("id"), + variable, +]); + +const foreachClause = new Cypher.Foreach(variable).in(list).do(createMovie); +---- + +== Other breaking changes + +=== Remove method `.children` from concat clauses + +[source, Javascript] +---- +const query = Cypher.utils.concat(clause1, clause2); +query.children; // No longer supported +---- + +=== Remove type `Cypher.Operation` +Remove type `Cypher.Operation` in favor of `Cypher.Expr` + +The type `Cypher.Operation` is no longer availabe, use `Cypher.Expr` instead: + +Before: +[source, javascript] +---- +const myOperation: Cypher.Operation = Cypher.and() +---- + +After: +[source, javascript] +---- +const myOperation: Cypher.Expr = Cypher.and() +---- + From b7bf8e22fbff4ac77d3d823f6831b1b162856a4e Mon Sep 17 00:00:00 2001 From: angrykoala Date: Thu, 30 Oct 2025 16:55:11 +0000 Subject: [PATCH 2/3] Add migration guide for version 3 --- docs/modules/ROOT/content-nav.adoc | 1 - .../modules/ROOT/pages/migration-guide-2.adoc | 450 ------------------ .../modules/ROOT/pages/migration-guide-3.adoc | 131 +++-- 3 files changed, 60 insertions(+), 522 deletions(-) delete mode 100644 docs/modules/ROOT/pages/migration-guide-2.adoc diff --git a/docs/modules/ROOT/content-nav.adoc b/docs/modules/ROOT/content-nav.adoc index f2e7c152..1a248a0a 100644 --- a/docs/modules/ROOT/content-nav.adoc +++ b/docs/modules/ROOT/content-nav.adoc @@ -44,7 +44,6 @@ ** xref:how-to/update-labels.adoc[] ** xref:how-to/define-cypher-version.adoc[] * xref:compatibility.adoc[] -* xref:migration-guide-2.adoc[] * xref:migration-guide-3.adoc[] * link:https://github.com/neo4j/cypher-builder/tree/main/examples[Examples] * link:https://neo4j.github.io/cypher-builder/reference/[Reference] diff --git a/docs/modules/ROOT/pages/migration-guide-2.adoc b/docs/modules/ROOT/pages/migration-guide-2.adoc deleted file mode 100644 index 533aadde..00000000 --- a/docs/modules/ROOT/pages/migration-guide-2.adoc +++ /dev/null @@ -1,450 +0,0 @@ -[[migration-2]] -:description: This page describes how to migrate to version 2.x -= Migration to Cypher Builder 2 - -This guide describes the changes required to migrate from Cypher Builder 1.x to 2.0, as well as some breaking changes that may affect projects using Cypher Builder. - -The full, up to date changelog can be found link:https://github.com/neo4j/cypher-builder/blob/main/CHANGELOG.md[here]. - -== Patterns - -xref:patterns.adoc[Patterns] have been reworked in version 1.x, and the old behavior have been removed in version 2.0. - - -=== Node shorthand removed from clauses - -Clauses using Patterns no longer accept a `Cypher.Node` as a shorthand. An explicit pattern must be provided: - - -Before: -[source, javascript] ----- -const movieNode = new Cypher.Node(); - -const matchQuery = new Cypher.Match(movieNode) ----- - - -Now: -[source, javascript] ----- -const movieNode = new Cypher.Node(); - -const matchQuery = new Cypher.Match( - new Cypher.Pattern(movieNode) -); ----- - -This affects all clauses using patterns: - -* `Cypher.Match` -* `Cypher.Create` -* `Cypher.Merge` - -This also affects pattern comprehensions `Cypher.PatternComprehension`. - - -=== Patterns no longer create a variable by default - -Creating a Pattern without options will no longer add variables to the generated Cypher: - -[source, javascript] ----- -const pattern = new Cypher.Pattern() ----- - -Before - -[source, cypher] ----- -(this0) ----- - -Now - -[source, cypher] ----- -() ----- - -To add a variable, it must be passed when creating the pattern: - -[source, javascript] ----- -const movieNode = new Cypher.Node(); -const pattern = new Cypher.Pattern(movieNode) ----- - - -==== `.getVariables` - -The method `.getVariables` has been removed from Patterns, as Patterns no longer create variables, `getVariables` is no longer useful. - -=== Patterns configuration - -The following methods to configure the resulting pattern have been removed from `Pattern`: - -- `.withoutLabels` -- `.withoutVariable` -- `.withProperties` -- `.withVariables` -- `.withoutType` -- `.withDirection` -- `.withLength` - -Instead, Patterns are now configured through objects in the constructor, as well as the `related` and `to` methods: - -Before -[source, javascript] ----- -const a = new Cypher.Node({ - labels: ["Person", "Actor"], -}); - -const aProperties = { - name: new Cypher.Param("Arthur"), - surname: new Cypher.Param("Dent"), -}; -const b = new Cypher.Node(); -const rel = new Cypher.Relationship({ - type: "ACTED_IN", -}); - -new Cypher.Pattern(a) - .withProperties({a: new Cypher.Param("Example")}) - .withoutVariable() - .related(rel) - .to(b) ----- - -Now - -[source, javascript] ----- -const aProperties = { - name: new Cypher.Param("Arthur"), - surname: new Cypher.Param("Dent"), -}; -const b = new Cypher.Node(); -const rel = new Cypher.Relationship(); - - -new Cypher.Pattern({ properties: aProperties, labels: ["Person", "Actor"] }) - .related(rel, { type: "ACTED_IN"}) - .to(b) ----- - - -The generated Cypher: - -[source, Cypher] ----- -(:Person:Actor { name: $param0, surname: $param1 })-[this1:ACTED_IN]->(this2) ----- - -Note that labels and types are now defined in the Pattern, not in the `Node` and `Relationship` classes. - -=== Assign to path variable - -The method `assignToPath` has been removed in the following clauses: - -- `Match` -- `Merge` -- `Create` - -Instead, the method `assignTo` in `Patterns` must be used: - -Before: - -```js -const pathVariable = new Cypher.Cypher.PathVariable() -new Cypher.Match(pattern).assignToPath(pathVariable).return(pathVariable); -``` - -Now: - -```js -const pathVariable = new Cypher.Cypher.PathVariable() -new Cypher.Match(pattern.assignTo(pathVariable)).return(pathVariable); -``` - -Generates the Cypher: - -```cypher -MATCH p = ()-[]-() -RETURN p -``` - - -== Node and Relationship variables - -`Cypher.Node` and `Cypher.Relationship` no longer hold any data about labels, or types. Making them more similar to `Cypher.Variable`. To add labels or types, these need to be passed to the `Cypher.Pattern` instead of relying on `Cypher.Node` and `Cypher.Relationship`. - -Before -[source, javascript] ----- -const a = new Cypher.Node({ - labels: ["Person", "Actor"], -}); -const b = new Cypher.Node(); -const rel = new Cypher.Relationship({ - type: "ACTED_IN", -}); - -new Cypher.Pattern(a) - .related(rel) - .to(b) ----- - -Now - -[source, javascript] ----- -const a = new Cypher.Node(); -const b = new Cypher.Node(); -const rel = new Cypher.Relationship(); - - -new Cypher.Pattern(a, { labels: ["Person", "Actor"] }) - .related(rel, { type: "ACTED_IN"}) - .to(b) ----- - -=== Path variables - -The variables used for paths `Cypher.Path` and `Cypher.NamedPath` have been removed in favor of the more accurate names: `Cypher.PathVariable` and `Cypher.NamedPathVariable` - -== Renamed features - -The following features where deprecated in favor of a different name with the same functionality. The deprecated features have been removed in version 2.0: - -* `Cypher.concat` in favor of `Cypher.utils.concat` -* `pointDistance` in favor of `point.distance` -* `Merge.onCreate` in favor of `Merge.onCreateSet` -* `Call.innerWith` in favor of `Call.importWith` -* `cdc` namespace in favor of `db.cdc` -** `db.cdc.current` -** `db.cdc.earliest` -** `db.cdc.query` -* `rTrim` and `lTrim` in favor of `rtrim` and `ltrim` respectively - -== `.build()` - -The options for `.build()` are now passed as a single object rather than parameters: - -Before: -[source, javascript] ----- -myClause.build( - "another-this", - { myParam: "hello"}, - { - labelOperator: "&" - } -); ----- - - -Now: -[source, javascript] ----- -myClause.build({ - prefix: "another-this", - extraParams: { - myParam: "hello", - }, - labelOperator: "&", -}); ----- - -All parameters are optional, and `build` can still be called without parameters. - -=== Remove support for fine-grained prefix - -The first parameter "prefix" for the `.build` method in 1.x supports passing an object with the parameters `params` and `variables` for fine grained control of what prefix to use in different kind of variables. This has been removed in 2.x, supporting only a `string` as global prefix: - -No longer supported: -[source, javascript] ----- -myClause.build({ - variable: "var_prefix_", - params: "param_prefix_" -}); ----- - -Instead, a single string can be used as prefix for both, variables and params: - -Now: -[source, javascript] ----- -myClause.build({ - prefix: "my-custom-prefix" -}); ----- - -== `With` - -The method `.with` no longer adds new columns into the existing clause. It will always create a new `WITH` statement instead. The method `.addColumns` should be used instead to add extra columns. - -Before -[source, javascript] ----- -const withQuery = new Cypher.With(node); -withQuery.with(node); -withQuery.with("*"); ----- - -Now -[source, javascript] ----- -const withQuery = new Cypher.With(node); -withQuery.with(node) -withQuery.addColumns("*"); ----- - - -The generated Cypher: - -[source, cypher] ----- -WITH this0 -WITH *, this0 ----- - -== `RawCypher` - -`Cypher.RawCypher` has been removed in favor of `Cypher.Raw`. - -=== Update callback parameter - -`Cypher.Raw` no longer exposes a `Cypher.Environment` variable. Instead, it provides an instance of `CypherRawContext` with a `compile` method to compile nested elements in custom cypher. - - -Before: -[source, typescript] ----- -const releasedParam = new Cypher.Param(1999); -const rawCypher = new Cypher.Raw((env: Cypher.Environment) => { - const releasedParamId = env.compile(releasedParam); // Gets the raw Cypher for the param - - const customCypher = `MATCH(n) WHERE n.title=$title_param AND n.released=${releasedParamId}`; - - return customCypher; -}); ----- - -Now: -[source, typescript] ----- -const releasedParam = new Cypher.Param(1999); -const rawCypher = new Cypher.Raw((ctx: Cypher.RawCypherContext) => { - const releasedParamId = ctx.compile(releasedParam); // Gets the raw Cypher for the param - - const customCypher = `MATCH(n) WHERE n.title=$title_param AND n.released=${releasedParamId}`; - - return customCypher; -}); ----- - -Note that the code itself has not changed, and just the type passed to `Cypher.Raw` callback has been changed from `Cypher.Environment` to `Cypher.RawCypherContext`. - -=== Remove `utils.compileCypher` - -The utility function `compileCypher` has been removed, in favor of using `CypherRawContext.compile`, which offers the same functionality. - -== `PatternComprehension` - -`PatternComprehension` no longer accept a node as an argument in the constructor, a Pattern must be passed instead: - -Before -[source, javascript] ----- -const node = new Cypher.Node(); -const comprehension = new Cypher.PatternComprehension(node); ----- - -Now -[source, javascript] ----- -const node = new Cypher.Node(); -const comprehension = new Cypher.PatternComprehension(new Cypher.Pattern(node)); ----- - -=== `.map` - -`PatternComprehension` no longer accepts a second argument for the Map expression. The method `.map` must be used instead: - -Before -[source, javascript] ----- -const andExpr = Cypher.eq(node.property("released"), new Cypher.Param(1999)); - -const comprehension = new Cypher.PatternComprehension(new Cypher.Pattern(node), andExpr) ----- - -Now -[source, javascript] ----- -const andExpr = Cypher.eq(node.property("released"), new Cypher.Param(1999)); - -const comprehension = new Cypher.PatternComprehension(new Cypher.Pattern(node)).map(andExpr); ----- - - -== Other Breaking changes - -These are breaking changes that do not require changes, but may affect the behaviour of projects updating to Cypher Builder 2.0. - - -=== Fix TypeScript typings for boolean operators - -The typings for the following boolean operators have been fixed to better reflect the result of these functions when spread parameters are used: - -* `Cypher.and` -* `Cypher.or` -* `Cypher.xor` - -The following: - -[source, typescript] ----- -const predicates: Cypher.Predicate[] = []; -const andPredicate = Cypher.and(...predicates); ----- - -Will now return the correct type `Cypher.Predicate | undefined`. This change means that additional checks may be needed when using boolean operators: - -[source, typescript] ----- -const predicates = [Cypher.true, Cypher.false]; -const andPredicate = Cypher.and(...predicates); // type Cypher.Predicate | undefined ----- - -Passing parameters without spread will still return a defined type. - - -=== Literals escaping - -`Cypher.Literal` will now escape strings if these contain invalid characters. This is to avoid code injection. - - -[source, javascript] ----- -new Cypher.Literal(`Hello "World"`); ----- - -Would generate the following Cypher: - -Before: -[source, cypher] ----- -"Hello "World"" ----- - -Now: -[source, cypher] ----- -"Hello \"World\"" ----- - -Note that `Cypher.Param` is still preferred over `Cypher.Literal` for dynamic values. diff --git a/docs/modules/ROOT/pages/migration-guide-3.adoc b/docs/modules/ROOT/pages/migration-guide-3.adoc index 87f2550f..99f6c230 100644 --- a/docs/modules/ROOT/pages/migration-guide-3.adoc +++ b/docs/modules/ROOT/pages/migration-guide-3.adoc @@ -2,71 +2,33 @@ :description: This page describes how to migrate to version 3.x from version 2 = Migration to Cypher Builder 3 -Cypher Builder 3 targets Cypher 5 and 25, dropping support for Cypher 4. If you need to support Cypher 4, stay with Cypher Builder 2.x, otherwise, migrate to version 3. +This guide details all the changes needed to migrate from Cypher Builder version 2 to version 3. + +[NOTE] +==== +If you need to support Neo4j 4, stay with Cypher Builder 2.x, otherwise, migrate to version 3. +==== == Compatibility changes === Minimum node engine changed to 20.0.0 -Node.js 16 is no longer supported. Update to version 20.0.0 or above. +Node.js 16 is no longer supported. Update Node.js to version 20.0.0 or above. === Cypher 4 no longer supported -Cypher 4, and Neo4j 4 databases are no longer supported. Cypher Builder targets Cypher 5 and 25 only. - - - - -== Remove support for apoc - -No apoc functions or procedures are supported in Cypher Builder 3. The following are no longer available: - -- `apoc.util.validate` -- `apoc.util.validatePredicate` -- `apoc.date.convertFormat` -- `apoc.cypher.runFirstColumnMany` -- `apoc.cypher.runFirstColumnSingle` - -To use apoc methods, create a xref:how-to/customize-cypher.adoc#_custom_functions_and_procedures[custom function or procedure]. For example: - -[source, Javascript] ----- -function validate( - predicate: Predicate, - message: string, - params: List | Literal | Map -): Cypher.VoidCypherProcedure { - return new Cypher.VoidCypherProcedure( - "apoc.util.validate", - [predicate, new Literal(message), params] - ); -} ----- - -[source, Javascript] ----- -function validatePredicate(predicate: Predicate, message: string): CypherFunction { - return new CypherFunction(" - apoc.util.validatePredicate", - [predicate, new Literal(message), new Literal([0])] - ); -} ----- - -== Cypher 4 only features - -The following features have been either removed or deprecated in Cypher 5, and are no longer available in Cypher Builder 3 +Cypher 4, and Neo4j 4 databases are no longer supported. Cypher Builder 3 targets Cypher 5 and 25. +The following features are Cypher 4 only, and have been removed from Cypher Builder. -=== Remove functions deprecated in Cypher 5 +==== Removed functions deprecated in Cypher 5 - `distance` in favor of `point.distance` - `id` in favor of `elementId` -=== Remove support for patterns in size +==== Removed support for patterns in size _No longer supported_ - [source, javascript] ---- Cypher.size(new Cypher.Pattern(node)); @@ -91,14 +53,12 @@ COUNT { } ---- +==== Removed `labelOperator` -=== Remove `labelOperator` - -Removed option `labelOperator`. All labels now use operator `&` +Removed option `labelOperator`. Now, the operator `&` is used by default when using multiple labels: _No longer supported_ - [source, javascript] ---- const { cypher, params } = matchQuery.build({ @@ -108,21 +68,19 @@ const { cypher, params } = matchQuery.build({ _Before_ - [source, Cypher] ---- MATCH (this1:Movie:Film) ---- _After_ - [source, Cypher] ---- MATCH (this1:Movie&Film) ---- -=== Remove `.importWith` from `Call` +==== Removed `.importWith` from `Call` Remove `.importWith` from `Call` clauses in favor of constructor options @@ -155,13 +113,48 @@ CALL (var0, var1){ } ---- +== Removed support for apoc -== ListComprehension +No apoc functions or procedures are supported in Cypher Builder 3. The following are no longer available: -The methods for `ListComprehension` have been changed to improve consistency with other elements of Cypher Builder. +- `apoc.util.validate` +- `apoc.util.validatePredicate` +- `apoc.date.convertFormat` +- `apoc.cypher.runFirstColumnMany` +- `apoc.cypher.runFirstColumnSingle` +To use apoc methods, create a xref:how-to/customize-cypher.adoc#_custom_functions_and_procedures[custom function or procedure]. For example: -=== Remove second parameter of constructor +[source, Javascript] +---- +function validate( + predicate: Predicate, + message: string, + params: List | Literal | Map +): Cypher.VoidCypherProcedure { + return new Cypher.VoidCypherProcedure( + "apoc.util.validate", + [predicate, new Literal(message), params] + ); +} +---- + +[source, Javascript] +---- +function validatePredicate(predicate: Predicate, message: string): CypherFunction { + return new CypherFunction(" + apoc.util.validatePredicate", + [predicate, new Literal(message), new Literal([0])] + ); +} +---- + +== API changes +The following are changes to the API, made to improve consistency across the Cypher Builder API. + +=== ListComprehension + +==== Remove second parameter of constructor Remove second parameter of `ListComprehension` constructor in favor of `.in` Before: @@ -182,7 +175,7 @@ In both cases, the same comprehension will be generated: [var0 IN [1, 2]] ``` -=== ListComprehension `.in` method no longer throws if called twice. +==== ListComprehension `.in` method no longer throws if called twice. ListComprehension `.in` method no longer throws if called twice. It will instead override the expression @@ -207,18 +200,15 @@ Will generate the following Cypher: Note that the same Cypher is generated if we omit the first `.in`: -After, this is valid: [source, javascript] ---- new Cypher.ListComprehension(variable).in(new Cypher.Literal([1])) ---- -== Foreach +=== Foreach -The methods for `Foreach` have been changed to improve consistency with other elements of Cypher Builder. - -=== Remove extra parameters in `Cypher.Foreach` constructor +==== Remove extra parameters in `Cypher.Foreach` constructor Remove extra parameters in `Cypher.Foreach` constructor in favor of methods `in` and `do`. For example, to create the following Cypher: @@ -232,7 +222,7 @@ FOREACH (var0 IN [1, 2, 3] | ) ---- -_before_ +_Before_ [source, javascript] ---- @@ -248,7 +238,7 @@ const createMovie = new Cypher.Create(new Cypher.Pattern(movieNode, { labels: [" const foreachClause = new Cypher.Foreach(variable, list, createMovie); ---- -_after_ +_After_ [source, javascript] ---- @@ -274,18 +264,17 @@ const query = Cypher.utils.concat(clause1, clause2); query.children; // No longer supported ---- -=== Remove type `Cypher.Operation` -Remove type `Cypher.Operation` in favor of `Cypher.Expr` +=== Remove type `Operation` The type `Cypher.Operation` is no longer availabe, use `Cypher.Expr` instead: -Before: +_Before_ [source, javascript] ---- const myOperation: Cypher.Operation = Cypher.and() ---- -After: +_After_ [source, javascript] ---- const myOperation: Cypher.Expr = Cypher.and() From 6c711c26fe7734e6b8f04a03d65057ed5fd40f53 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Thu, 30 Oct 2025 17:02:46 +0000 Subject: [PATCH 3/3] Update docs to v3 --- .../ROOT/pages/build-configuration.adoc | 3 +- docs/modules/ROOT/pages/clauses/with.adoc | 2 +- docs/modules/ROOT/pages/compatibility.adoc | 10 ++-- .../pages/getting-started/installation.adoc | 2 +- .../pages/how-to/define-cypher-version.adoc | 4 +- docs/modules/ROOT/pages/subqueries/call.adoc | 48 ------------------- .../pages/variables-and-params/lists.adoc | 9 +--- 7 files changed, 11 insertions(+), 67 deletions(-) diff --git a/docs/modules/ROOT/pages/build-configuration.adoc b/docs/modules/ROOT/pages/build-configuration.adoc index 6483ad9c..19f96479 100644 --- a/docs/modules/ROOT/pages/build-configuration.adoc +++ b/docs/modules/ROOT/pages/build-configuration.adoc @@ -14,8 +14,7 @@ The method `build` accepts an object with options to configure the build process [cols="2,1,1,3",options="header"] |=== | Setting | Type | Default | Description -| `labelOperator` | String | `":"` | Define the default operator to use when using multiple labels in a Pattern. It can be either `:` or `&` -| `cypherVersion` | String | `undefined` | If set, will prepend all queries with a `CYPHER [Version]` statement. The only valid value is `"5"` +| `cypherVersion` | String | `undefined` | If set, will prepend all queries with a `CYPHER [Version]` statement. The possible values are `"5"` and `"25"` | `prefix` | String | `undefined` | If set, will add a prefix to all variable names. See xref:how-to/customize-cypher.adoc#_build_prefix[Customize Cypher] | `extraParams` | Object | `{}` | Add the provided parameters to the resulting params object. See xref:variables-and-params/parameters.adoc#_adding_extra_parameters[Parameters] | `unsafeEscapeOptions` | Object | `{}` | Set of options to disable escaping from generated Cypher. See xref:_unsafe_escape_options[Unsafe escape options] diff --git a/docs/modules/ROOT/pages/clauses/with.adoc b/docs/modules/ROOT/pages/clauses/with.adoc index 3e309f6a..5977f7d0 100644 --- a/docs/modules/ROOT/pages/clauses/with.adoc +++ b/docs/modules/ROOT/pages/clauses/with.adoc @@ -2,7 +2,7 @@ :description: This page describes how to create `WITH` clauses. = With -This page describes how to create a link:https://neo4j.com/docs/cypher-manual/current/clauses/with/[`WITH`] clause using the `Cypher.With` class. Note that this is different to the xref:../subqueries/call.adoc#_importwith[ImportWith] statement inside `CALL`. +This page describes how to create a link:https://neo4j.com/docs/cypher-manual/current/clauses/with/[`WITH`] clause using the `Cypher.With` class. A `With` clause will take multiple parameters. Variables can be passed directly without aliasing: diff --git a/docs/modules/ROOT/pages/compatibility.adoc b/docs/modules/ROOT/pages/compatibility.adoc index d6e69c41..14be8ea3 100644 --- a/docs/modules/ROOT/pages/compatibility.adoc +++ b/docs/modules/ROOT/pages/compatibility.adoc @@ -1,13 +1,13 @@ [[compatibility]] -:description: This page outlines the compatibility requirements for `@neo4j/cypher-builder` version 2 with Cypher and Node.js. +:description: This page outlines the compatibility requirements for `@neo4j/cypher-builder` version 3 with Cypher and Node.js. = Compatibility -This page outlines the compatibility requirements for `@neo4j/cypher-builder` version 2 with Cypher and Node.js. +This page outlines the compatibility requirements for `@neo4j/cypher-builder` version 3 with Cypher and Node.js. -* Targets link:https://neo4j.com/docs/cypher-manual/5/introduction/[Cypher 5], with support for link:https://neo4j.com/docs/cypher-manual/4.4/introduction/[Cypher 4.4]. -* Compatible with Node.js version 16.0.0 and later. +* Targets link:https://neo4j.com/docs/cypher-manual/25/introduction/[Cypher 25], with support for link:https://neo4j.com/docs/cypher-manual/5/introduction/[Cypher 5]. +* Compatible with Node.js version 20.0.0 and later. [NOTE] ==== -`@neo4j/cypher-builder` version 1 is no longer supported. Version 2 is a full replacement and maintains the same compatibility with Cypher and Node.js. +If you need to support Neo4j 4, stay with Cypher Builder 2.x, otherwise, xref:migration-guide-3.adoc#migration[migrate to version 3]. ==== diff --git a/docs/modules/ROOT/pages/getting-started/installation.adoc b/docs/modules/ROOT/pages/getting-started/installation.adoc index 5cc36e55..a095df21 100644 --- a/docs/modules/ROOT/pages/getting-started/installation.adoc +++ b/docs/modules/ROOT/pages/getting-started/installation.adoc @@ -6,7 +6,7 @@ This guide shows how to start using Cypher Builder by setting up a Node.js proje == Requirements -* link:https://nodejs.org/[Node.js] 16.0.0 or greater +* link:https://nodejs.org/[Node.js] 20.0.0 or greater * link:https://docs.npmjs.com/downloading-and-installing-node-js-and-npm[npm] * **[Optional]** A link:https://neo4j.com/cloud/platform/aura-graph-database/?ref=nav-get-started-cta[Neo4j] database to try Cypher queries. diff --git a/docs/modules/ROOT/pages/how-to/define-cypher-version.adoc b/docs/modules/ROOT/pages/how-to/define-cypher-version.adoc index cd7a5af3..34a6f8b6 100644 --- a/docs/modules/ROOT/pages/how-to/define-cypher-version.adoc +++ b/docs/modules/ROOT/pages/how-to/define-cypher-version.adoc @@ -2,7 +2,7 @@ :description: This page describes how to define the Cypher version to be used in the query. = Define Cypher version -It is possible to define the version of Cypher to use in a query by prepending that query with `CYPHER [version]`. For example: +It is possible to explicitly define the version of Cypher to use in a query by prepending that query with `CYPHER [version]`. For example: [source, cypher] @@ -13,7 +13,7 @@ RETURN this0 ---- -To add the Cypher version at the beggining of the query, pass the parameter `cypherVersion` to `.build`: +To add the Cypher version at the beggining of the query, pass the parameter `cypherVersion` to `.build`. The possible values are `"5"` and `"25"`: [source, javascript] ---- diff --git a/docs/modules/ROOT/pages/subqueries/call.adoc b/docs/modules/ROOT/pages/subqueries/call.adoc index 9a8641c8..313224fc 100644 --- a/docs/modules/ROOT/pages/subqueries/call.adoc +++ b/docs/modules/ROOT/pages/subqueries/call.adoc @@ -83,54 +83,6 @@ CALL (*) { } ---- -[role=label--deprecated] -== `.importWith` - -[WARNING] -==== -This method is deprecated in favor of <<_variable_scope>>. -==== - -[WARNING] -==== -`importWith` cannot be used if scope variables are defined and will throw an error. -==== - - -To add variables to a `CALL` subquery context, you need to add a `WITH` statement. This can be achieved by using the `.importWith` method. - -[source, javascript] ----- -const dog = new Cypher.Node(); -const person = new Cypher.Node(); - -const dogName = new Cypher.NamedVariable("dogName"); - -const subquery = new Cypher.Match( - new Cypher.Pattern(person, { labels: ["Person"] }) - .related(new Cypher.Relationship({ type: "HAS_DOG" })) - .to(dog, { labels: ["Dog"] }) -).return([dog.property("name"), dogName]); - -const clause = new Cypher.Match(new Cypher.Pattern(person, { labels: ["Person"] })) - .call(subquery) - .importWith(person) - .return(dogName); ----- - -[source, cypher] ----- -MATCH (this0:Person) -CALL { - WITH this0 - MATCH (this0:Person)-[this1:HAS_DOG]->(this2:Dog) - RETURN this2.name AS dogName -} -RETURN dogName ----- - -Note how this example uses `.concat` to combine the initial `MATCH` and `CALL` clauses. - == `.inTransactions` The `.inTransactions` method appends the `IN TRANSACTIONS` modifier to a `CALL` subquery, causing it to link:https://neo4j.com/docs/cypher-manual/current/subqueries/subqueries-in-transactions/[execute in separate transactions]: diff --git a/docs/modules/ROOT/pages/variables-and-params/lists.adoc b/docs/modules/ROOT/pages/variables-and-params/lists.adoc index 3f52b032..c94a228d 100644 --- a/docs/modules/ROOT/pages/variables-and-params/lists.adoc +++ b/docs/modules/ROOT/pages/variables-and-params/lists.adoc @@ -98,7 +98,7 @@ You also need an expression resulting in the original list to create a new list [source, javascript] ---- -const listComprehension = new Cypher.ListComprehension(variable, new Cypher.Literal([1,2])) +const listComprehension = new Cypher.ListComprehension(variable).in(new Cypher.Literal([1,2])) ---- [source, cypher] @@ -106,13 +106,6 @@ const listComprehension = new Cypher.ListComprehension(variable, new Cypher.Lite [var0 IN [1,2]] ---- -Alternatively, the original list expression can be passed with the method `.in`: - -[source, javascript] ----- -const listComprehension = new Cypher.ListComprehension(variable).in(new Cypher.Literal([1,2])) ----- - By using the methods `where` and `map`, you can construct the filter and mapping parts of the comprehension: