From 4d9049b1d1ba6d62333dda3d051e401f4ad84c5f Mon Sep 17 00:00:00 2001 From: Gemma Lamont Date: Mon, 27 Oct 2025 13:27:35 +0100 Subject: [PATCH 1/5] Add collection function docs --- ...ions-additions-removals-compatibility.adoc | 29 ++ modules/ROOT/pages/functions/index.adoc | 32 ++ modules/ROOT/pages/functions/list.adoc | 427 +++++++++++++++++- 3 files changed, 487 insertions(+), 1 deletion(-) diff --git a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc index 7e2276a36..2990b34e0 100644 --- a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc +++ b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc @@ -22,6 +22,35 @@ Cypher 25 was introduced in Neo4j 2025.06 and can only be used on Neo4j 2025.06+ Features removed in Cypher 25 are still available on Neo4j 2025.06+ databases either by prepending a query with `CYPHER 5` or by having Cypher 5 as the default language for the database. For more information, see xref:queries/select-version.adoc[]. +[[cypher-deprecations-additions-removals-2025.11]] +== Neo4j 2025.11 + +=== Updated in Cypher 25 + +[cols="2", options="header"] +|=== +| Feature +| Details + +a| +label:functionality[] +label:new[] +[source, cypher, role="noheader"] +---- +RETURN coll.distinct([true, false, false, true, true, false]) +RETURN coll.flatten([1, [2]]), coll.flatten([false, ['a']], 2); +RETURN coll.indexOf(['A', 'new', 'function'], 'new'); +RETURN coll.insert([1, 2, 4], 2, 3); +RETURN coll.max([1.5, 2, 5.4, 0, 4]); +RETURN coll.min([1.5, 2, 5.4, 0, 4]); +RETURN coll.remove(['a', 'a', 'b', 'c', 'd'], 2); +RETURN coll.sort([3, 1, 4, 2, 'a', 'c', 'b']); +---- +| Introduction of eight new collection based Cypher functions. +For more information, see xref:functions/list.adoc[List functions - lists]. + +|=== + [[cypher-deprecations-additions-removals-2025.10]] == Neo4j 2025.10 diff --git a/modules/ROOT/pages/functions/index.adoc b/modules/ROOT/pages/functions/index.adoc index fdba301a4..1432bdc04 100644 --- a/modules/ROOT/pages/functions/index.adoc +++ b/modules/ROOT/pages/functions/index.adoc @@ -128,6 +128,38 @@ Further details and examples of lists may be found in xref::values-and-types/lis | Function | Signature | Description +1.1+| xref::functions/list.adoc#functions-coll-distinct[`coll.distinct()`] +| `coll.distinct(list :: LIST) :: LIST` +| Returns the given list with all duplicate values removed. + +1.1+| xref::functions/list.adoc#functions-coll-flatten[`coll.flatten()`] +| `coll.flatten(list :: LIST, depth = 1 :: INTEGER) :: LIST` +| Returns a list flattened to the given depth. + +1.1+| xref::functions/list.adoc#functions-coll-indexOf[`coll.indexOf()`] +| `coll.indexOf(list :: LIST, value :: ANY) :: INTEGER` +| Returns the index for the first match of value in the given list, if the value is no present, -1 is returned. + +1.1+| xref::functions/list.adoc#functions-coll-insert[`coll.insert()`] +| `coll.insert(list :: LIST, index :: INTEGER, value :: ANY) :: LIST` +| Returns a list with the given value inserted at the given index. + +1.1+| xref::functions/list.adoc#functions-coll-max[`coll.max()`] +| `coll.max(list :: LIST) :: ANY` +| Returns the largest value. + +1.1+| xref::functions/list.adoc#functions-coll-min[`coll.min()`] +| `coll.min(list :: LIST) :: ANY` +| Returns the smallest value. + +1.1+| xref::functions/list.adoc#functions-coll-remove[`coll.remove()`] +| `coll.remove(list :: LIST, index :: INTEGER) :: LIST` +| Returns a list with the value at the given index removed. + +1.1+| xref::functions/list.adoc#functions-coll-sort[`coll.sort()`] +| `coll.sort(list :: LIST) :: LIST` +| Returns a sorted list. + 1.1+| xref::functions/list.adoc#functions-keys[`keys()`] | `keys(input :: NODE \| RELATIONSHIP \| MAP) :: LIST` | Returns a `LIST` containing the `STRING` representations for all the property names of a `MAP`, `NODE`, or `RELATIONSHIP`. diff --git a/modules/ROOT/pages/functions/list.adoc b/modules/ROOT/pages/functions/list.adoc index 3d5c59010..2ecb895d6 100644 --- a/modules/ROOT/pages/functions/list.adoc +++ b/modules/ROOT/pages/functions/list.adoc @@ -27,7 +27,7 @@ CREATE (alice:Developer {name:'Alice', age: 38, eyes: 'Brown'}), (bob:Administrator {name: 'Bob', age: 25, eyes: 'Blue'}), (charlie:Administrator {name: 'Charlie', age: 53, eyes: 'Green'}), - (daniel:Adminstrator {name: 'Daniel', age: 54, eyes: 'Brown'}), + (daniel:Administrator {name: 'Daniel', age: 54, eyes: 'Brown'}), (eskil:Designer {name: 'Eskil', age: 41, eyes: 'blue', likedColors: ['Pink', 'Yellow', 'Black']}), (alice)-[:KNOWS]->(bob), (alice)-[:KNOWS]->(charlie), @@ -36,6 +36,431 @@ CREATE (bob)-[:MARRIED]->(eskil) ---- +[[functions-coll-distinct]] +== coll.distinct() + +.Details +|=== +| *Syntax* 3+| `coll.distinct(list)` +| *Description* 3+| Returns the given list with all duplicate values removed. +.2+| *Arguments* | *Name* | *Type* | *Description* +| `list` | `LIST` | A list to be deduplicated. +| *Returns* 3+| `LIST` +|=== + +.Considerations +|=== +| `coll.distinct(null)` returns `null`. +| The order of the first occurrences is preserved. +|=== + +.+coll.distinct()+ +====== + +.Deduplicate a list of integer values +// tag::functions_list_distinct[] +[source, cypher] +---- +RETURN coll.distinct([1, 3, 2, 4, 2, 3, 1]) +---- +// end::functions_list_distinct[] + +A `LIST` containing only unique values is returned. + +.Result +[role="queryresult",options="header,footer",cols="1*` containing only unique values is returned. + +.Result +[role="queryresult",options="header,footer",cols="1*` | A list to be flattened. +| `depth` | `INTEGER` | The maximum depth to flatten to (default value: 1). +| *Returns* 3+| `LIST` +|=== + +.Considerations +|=== +| Preserves the original order of non-list items. +| If `depth` is 0, the input list is returned unchanged. +| `depth` must be a non-negative integer. +| `coll.flatten(null)` returns `null`. +| `coll.flatten(list, null)` returns `null`. +| `coll.flatten(null, depth)` returns `null`. +| `coll.flatten(null, null)` returns `null`. + +|=== + + +.+coll.flatten()+ +====== + +.Flatten a list containing nesting to level 2 +// tag::functions_list_flatten[] +[source, cypher] +---- +RETURN coll.flatten(['a', ['b', ['c']]], 2) +---- +// end::functions_list_flatten[] + +A `LIST` with any inner lists up to a nesting depth of 2 flattened. + +.Result +[role="queryresult",options="header,footer",cols="1*` with any inner lists up to a nesting depth of 1 (default depth) flattened. + +.Result +[role="queryresult",options="header,footer",cols="1*` | A list to be searched. +| `value` | `ANY` | A value to search for. +| *Returns* 3+| `INTEGER` +|=== + +.Considerations +|=== + +| Indexing is 0-based. +| Returns -1 if the value is not present in the list. +| `coll.indexOf(null, null)` returns `null`. +| `coll.indexOf(null, value)` returns `null`. +| `coll.indexOf(list, null)` returns `null`. + +|=== + + +.+coll.indexOf()+ +====== + +.Find the first index of a given value +// tag::functions_list_indexOf[] +[source, cypher] +---- +RETURN coll.indexOf(['a', 'b', 'c', 'c'], 'c') +---- +// end::functions_list_indexOf[] + +An `INTEGER` representing the index of the item in the list. + +.Result +[role="queryresult",options="header,footer",cols="1*` | A list to add to. +| `index` | `INTEGER` | The index to add the given value at. +| `value` | `ANY` | The value to add into the list. +| *Returns* 3+| `LIST` +|=== + +.Considerations +|=== +| Indexing is 0-based. +| `coll.insert(null, null, value)` returns `null`. +| `coll.insert(list, null, value)` returns `null`. +| `coll.insert(null, 1, value)` returns `null`. +| If the given `index` is negative or larger than the size of the given list, an error will be returned. + +|=== + + +.+coll.insert()+ +====== + +.Query +// tag::functions_list_insert[] +[source, cypher] +---- +RETURN coll.insert([true, 'a', 1, 5.4], 1, false) +---- +// end::functions_list_insert[] + +The original list with a new value inserted at the given index. + +.Result +[role="queryresult",options="header,footer",cols="1*` | A list to be searched. +| *Returns* 3+| `ANY` +|=== + +.Considerations +|=== +| `coll.max(null)` returns `null`. +| `coll.max([])` returns `null`. +| The maximum is determined using Cypher's standard value ordering; see xref:values-and-types/ordering-equality-comparison.adoc[]. +|=== + + +.+coll.max()+ +====== + +.Query +// tag::functions_list_max[] +[source, cypher] +---- +RETURN coll.max([true, 'a', 1, 5.4]) +---- +// end::functions_list_max[] + +The maximum value found in the given list based on Cypher's ordering. + +.Result +[role="queryresult",options="header,footer",cols="1*` | A list to be searched. +| *Returns* 3+| `ANY` +|=== + +.Considerations +|=== +| `coll.min(null)` returns `null`. +| `coll.min([])` returns `null`. +| The minimum is determined using Cypher's standard value ordering; see xref:values-and-types/ordering-equality-comparison.adoc[]. +|=== + + +.+coll.min()+ +====== + +.Query +// tag::functions_list_min[] +[source, cypher] +---- +RETURN coll.min([true, 'a', 1, 5.4]) +---- +// end::functions_list_min[] + +The minimum value found in the given list based on Cypher's ordering. + +.Result +[role="queryresult",options="header,footer",cols="1*` | A list to remove a value from. +| `index` | `INTEGER` | The index of the value to be removed. +| *Returns* 3+| `LIST` +|=== + +.Considerations +|=== +| Indexing is 0-based. +| `coll.remove(null, null)` returns `null`. +| `coll.remove(null, index)` returns `null`. +| `coll.remove(list, null)` returns `null`. +| If the given `index` is negative or larger than the size of the given list, an error will be returned. + +|=== + + +.+coll.remove()+ +====== + +.Query +// tag::functions_list_remove[] +[source, cypher] +---- +RETURN coll.remove([true, 'a', 1, 5.4], 1) +---- +// end::functions_list_remove[] + +The original list with the value at the given index removed and all items following shifted forward by 1. + +.Result +[role="queryresult",options="header,footer",cols="1*` | A list to be sorted. +| *Returns* 3+| `LIST` +|=== + +.Considerations +|=== +| Sorting follows Cypher's standard value ordering; see xref:values-and-types/ordering-equality-comparison.adoc[]. +| `coll.sort(null)` returns `null`. + +|=== + + +.+coll.sort()+ +====== + +.Query +// tag::functions_list_sort[] +[source, cypher] +---- +RETURN coll.sort([true, 'a', 1, 2]) +---- +// end::functions_list_sort[] + +The list sorted using Cypher's ordering in ascending order. + +.Result +[role="queryresult",options="header,footer",cols="1* Date: Tue, 28 Oct 2025 13:03:13 +0100 Subject: [PATCH 2/5] Apply suggestions from code review Co-authored-by: Richard Sill <156673635+rsill-neo4j@users.noreply.github.com> --- ...recations-additions-removals-compatibility.adoc | 2 +- modules/ROOT/pages/functions/list.adoc | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc index 2990b34e0..7b8d6fd73 100644 --- a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc +++ b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc @@ -46,7 +46,7 @@ RETURN coll.min([1.5, 2, 5.4, 0, 4]); RETURN coll.remove(['a', 'a', 'b', 'c', 'd'], 2); RETURN coll.sort([3, 1, 4, 2, 'a', 'c', 'b']); ---- -| Introduction of eight new collection based Cypher functions. +| Introduction of eight new collection-based Cypher functions. For more information, see xref:functions/list.adoc[List functions - lists]. |=== diff --git a/modules/ROOT/pages/functions/list.adoc b/modules/ROOT/pages/functions/list.adoc index 2ecb895d6..1cd0a1fad 100644 --- a/modules/ROOT/pages/functions/list.adoc +++ b/modules/ROOT/pages/functions/list.adoc @@ -51,7 +51,7 @@ CREATE .Considerations |=== | `coll.distinct(null)` returns `null`. -| The order of the first occurrences is preserved. +| The order of the first occurrences of the distinct values is preserved. |=== .+coll.distinct()+ @@ -103,9 +103,9 @@ A `LIST` containing only unique values is returned. .Details |=== | *Syntax* 3+| `coll.flatten(list [, depth])` -| *Description* 3+| Returns a list flattened to the given depth. +| *Description* 3+| Returns a list flattened to the given nesting depth. .3+| *Arguments* | *Name* | *Type* | *Description* -| `list` | `LIST` | A list to be flattened. +| `list` | `LIST` | A nested list to be flattened. | `depth` | `INTEGER` | The maximum depth to flatten to (default value: 1). | *Returns* 3+| `LIST` |=== @@ -171,7 +171,7 @@ A `LIST` with any inner lists up to a nesting depth of 1 (default depth) fl .Details |=== | *Syntax* 3+| `coll.indexOf(list, value)` -| *Description* 3+| Returns the index for the first match of value in the given list, if the value is not present, -1 is returned. +| *Description* 3+| Returns the index for the first match of a value in the given list or -1 if the value is not present. .3+| *Arguments* | *Name* | *Type* | *Description* | `list` | `LIST` | A list to be searched. | `value` | `ANY` | A value to search for. @@ -252,7 +252,7 @@ The `INTEGER` -1 representing that the value is not found. | `coll.insert(null, null, value)` returns `null`. | `coll.insert(list, null, value)` returns `null`. | `coll.insert(null, 1, value)` returns `null`. -| If the given `index` is negative or larger than the size of the given list, an error will be returned. +| If the given `index` is negative or larger than the size of the given list, an error is returned. |=== @@ -387,7 +387,7 @@ The minimum value found in the given list based on Cypher's ordering. | `coll.remove(null, null)` returns `null`. | `coll.remove(null, index)` returns `null`. | `coll.remove(list, null)` returns `null`. -| If the given `index` is negative or larger than the size of the given list, an error will be returned. +| If the given `index` is negative or larger than the size of the given list, an error is returned. |=== @@ -403,7 +403,7 @@ RETURN coll.remove([true, 'a', 1, 5.4], 1) ---- // end::functions_list_remove[] -The original list with the value at the given index removed and all items following shifted forward by 1. +The original list with the value at the given index removed and all items following shifted by 1. .Result [role="queryresult",options="header,footer",cols="1* Date: Tue, 28 Oct 2025 13:37:39 +0100 Subject: [PATCH 3/5] PR review updates --- modules/ROOT/pages/functions/list.adoc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/modules/ROOT/pages/functions/list.adoc b/modules/ROOT/pages/functions/list.adoc index 1cd0a1fad..448904e5f 100644 --- a/modules/ROOT/pages/functions/list.adoc +++ b/modules/ROOT/pages/functions/list.adoc @@ -58,12 +58,12 @@ CREATE ====== .Deduplicate a list of integer values -// tag::functions_list_distinct[] +// tag::functions_list_distinct_ints[] [source, cypher] ---- RETURN coll.distinct([1, 3, 2, 4, 2, 3, 1]) ---- -// end::functions_list_distinct[] +// end::functions_list_distinct_ints[] A `LIST` containing only unique values is returned. @@ -77,12 +77,12 @@ A `LIST` containing only unique values is returned. |=== .Deduplicate a list of mixed values, including null -// tag::functions_list_distinct[] +// tag::functions_list_distinct_mixed[] [source, cypher] ---- RETURN coll.distinct([1, true, true, null, 'a', false, true, 1, null]) ---- -// end::functions_list_distinct[] +// end::functions_list_distinct_mixed[] A `LIST` containing only unique values is returned. @@ -146,12 +146,12 @@ A `LIST` with any inner lists up to a nesting depth of 2 flattened. |=== .Flatten a list to default of depth 1 -// tag::functions_list_flatten[] +// tag::functions_list_flatten_default[] [source, cypher] ---- RETURN coll.flatten(['a', ['b', ['c']]]) ---- -// end::functions_list_flatten[] +// end::functions_list_flatten_default[] A `LIST` with any inner lists up to a nesting depth of 1 (default depth) flattened. @@ -213,12 +213,12 @@ An `INTEGER` representing the index of the item in the list. |=== .Search for a value not present in the given list -// tag::functions_list_indexOf[] +// tag::functions_list_indexOf_missing[] [source, cypher] ---- RETURN coll.indexOf([1, 'b', false], 4.3) ---- -// end::functions_list_indexOf[] +// end::functions_list_indexOf_missing[] The `INTEGER` -1 representing that the value is not found. @@ -268,7 +268,7 @@ RETURN coll.insert([true, 'a', 1, 5.4], 1, false) ---- // end::functions_list_insert[] -The original list with a new value inserted at the given index. +The original list with a new value inserted at the given index, shifting all the values following by 1. .Result [role="queryresult",options="header,footer",cols="1* Date: Tue, 28 Oct 2025 14:07:18 +0100 Subject: [PATCH 4/5] Update modules/ROOT/pages/functions/list.adoc Co-authored-by: Richard Sill <156673635+rsill-neo4j@users.noreply.github.com> --- modules/ROOT/pages/functions/list.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ROOT/pages/functions/list.adoc b/modules/ROOT/pages/functions/list.adoc index 448904e5f..952a29ec2 100644 --- a/modules/ROOT/pages/functions/list.adoc +++ b/modules/ROOT/pages/functions/list.adoc @@ -403,7 +403,7 @@ RETURN coll.remove([true, 'a', 1, 5.4], 1) ---- // end::functions_list_remove[] -The original list with the value at the given index removed and all items following shifted by 1. +The original list with the value at the given index removed and all values following shifted by 1. .Result [role="queryresult",options="header,footer",cols="1* Date: Mon, 3 Nov 2025 08:35:49 +0100 Subject: [PATCH 5/5] Apply suggestions from code review Co-authored-by: Richard Sill <156673635+rsill-neo4j@users.noreply.github.com> --- modules/ROOT/pages/functions/index.adoc | 2 +- modules/ROOT/pages/functions/list.adoc | 12 +++--------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/modules/ROOT/pages/functions/index.adoc b/modules/ROOT/pages/functions/index.adoc index 1432bdc04..82cc5119a 100644 --- a/modules/ROOT/pages/functions/index.adoc +++ b/modules/ROOT/pages/functions/index.adoc @@ -138,7 +138,7 @@ Further details and examples of lists may be found in xref::values-and-types/lis 1.1+| xref::functions/list.adoc#functions-coll-indexOf[`coll.indexOf()`] | `coll.indexOf(list :: LIST, value :: ANY) :: INTEGER` -| Returns the index for the first match of value in the given list, if the value is no present, -1 is returned. +| Returns the index of the first match of value in the given list, if the value is no present, -1 is returned. 1.1+| xref::functions/list.adoc#functions-coll-insert[`coll.insert()`] | `coll.insert(list :: LIST, index :: INTEGER, value :: ANY) :: LIST` diff --git a/modules/ROOT/pages/functions/list.adoc b/modules/ROOT/pages/functions/list.adoc index 952a29ec2..976b4a6ba 100644 --- a/modules/ROOT/pages/functions/list.adoc +++ b/modules/ROOT/pages/functions/list.adoc @@ -58,12 +58,10 @@ CREATE ====== .Deduplicate a list of integer values -// tag::functions_list_distinct_ints[] [source, cypher] ---- RETURN coll.distinct([1, 3, 2, 4, 2, 3, 1]) ---- -// end::functions_list_distinct_ints[] A `LIST` containing only unique values is returned. @@ -77,12 +75,12 @@ A `LIST` containing only unique values is returned. |=== .Deduplicate a list of mixed values, including null -// tag::functions_list_distinct_mixed[] +// tag::functions_list_distinct[] [source, cypher] ---- RETURN coll.distinct([1, true, true, null, 'a', false, true, 1, null]) ---- -// end::functions_list_distinct_mixed[] +// end::functions_list_distinct[] A `LIST` containing only unique values is returned. @@ -146,12 +144,10 @@ A `LIST` with any inner lists up to a nesting depth of 2 flattened. |=== .Flatten a list to default of depth 1 -// tag::functions_list_flatten_default[] [source, cypher] ---- RETURN coll.flatten(['a', ['b', ['c']]]) ---- -// end::functions_list_flatten_default[] A `LIST` with any inner lists up to a nesting depth of 1 (default depth) flattened. @@ -171,7 +167,7 @@ A `LIST` with any inner lists up to a nesting depth of 1 (default depth) fl .Details |=== | *Syntax* 3+| `coll.indexOf(list, value)` -| *Description* 3+| Returns the index for the first match of a value in the given list or -1 if the value is not present. +| *Description* 3+| Returns the index of the first match of a value in the given list or -1 if the value is not present. .3+| *Arguments* | *Name* | *Type* | *Description* | `list` | `LIST` | A list to be searched. | `value` | `ANY` | A value to search for. @@ -213,12 +209,10 @@ An `INTEGER` representing the index of the item in the list. |=== .Search for a value not present in the given list -// tag::functions_list_indexOf_missing[] [source, cypher] ---- RETURN coll.indexOf([1, 'b', false], 4.3) ---- -// end::functions_list_indexOf_missing[] The `INTEGER` -1 representing that the value is not found.