From 5a4b351330de65db4bea6aa202aeaa9c71e4404f Mon Sep 17 00:00:00 2001 From: imilinovic Date: Mon, 20 Jul 2026 15:32:09 +0200 Subject: [PATCH 1/4] docs: Document NULL handling for collections functions --- .../available-algorithms/collections.mdx | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/pages/advanced-algorithms/available-algorithms/collections.mdx b/pages/advanced-algorithms/available-algorithms/collections.mdx index 339874be6..b2d6449da 100644 --- a/pages/advanced-algorithms/available-algorithms/collections.mdx +++ b/pages/advanced-algorithms/available-algorithms/collections.mdx @@ -39,6 +39,44 @@ uncomparable.
Only `Numeric` data types can be used in `sum()` and `avg()` functions, so only `Int` and `Double` data types are allowed. +### Handling `NULL` values + +Passing `NULL` as a whole list (or scalar) argument no longer raises an +argument-validation error. Each function returns a defined result: + +| Function | Result when a list argument is `NULL` | +| --- | --- | +| `sum()`, `sum_longs()`, `avg()`, `min()`, `max()`, `to_set()`, `pairs()` | `null` | +| `union()`, `union_all()` | the other list; `null` when both are `NULL` | +| `remove_all()` | `null` when the first list is `NULL`; the first list when the second is `NULL` | +| `intersection()`, `sort()`, `flatten()` | empty list `[]` | +| `contains()`, `contains_all()`, `contains_sorted()` | `false` | +| `frequencies_as_map()` | empty map `{}` | +| `split()`, `partition()` | no rows | + +`NULL` elements inside a list are handled per function: + +- `min()` and `max()` skip `NULL` elements; a list containing only `NULL` values returns `null`. +- `contains()` and `contains_all()` never match a `NULL` search value (`NULL = NULL` is not true), so searching for `NULL` returns `false`. +- `split()` treats a `NULL` delimiter as matching nothing and returns the whole list as a single part; `NULL` list elements are kept. +- `frequencies_as_map()` counts `NULL` elements under the `"NO_VALUE"` key. +- `flatten()`, `pairs()`, `to_set()`, `union()`, `union_all()`, `remove_all()` and `intersection()` keep `NULL` elements as ordinary values. +- `sum()`, `sum_longs()`, `avg()`, `sort()` and `contains_sorted()` still reject a list that contains a `NULL` element; `contains_sorted()` also rejects a `NULL` search value, and `partition()` still rejects a `NULL` size. + +For example, a `NULL` argument returns the defined result instead of erroring: + +```cypher +RETURN collections.sum(null) AS sum, collections.sort(null) AS sorted; +``` + +```plaintext ++----------------------------+ +| sum | sorted | ++----------------------------+ +| null | [] | ++----------------------------+ +``` + ### `sort()` Sorts the elements of an input list if they are of the same data type. For the input From 137774d92df795f05cfa3b3b8f1cfc6f10408156 Mon Sep 17 00:00:00 2001 From: imilinovic Date: Mon, 20 Jul 2026 16:48:09 +0200 Subject: [PATCH 2/4] docs: Document collections.disjunction, subtract, and duplicates --- .../available-algorithms/collections.mdx | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/pages/advanced-algorithms/available-algorithms/collections.mdx b/pages/advanced-algorithms/available-algorithms/collections.mdx index b2d6449da..a85c115bc 100644 --- a/pages/advanced-algorithms/available-algorithms/collections.mdx +++ b/pages/advanced-algorithms/available-algorithms/collections.mdx @@ -333,6 +333,107 @@ RETURN collections.intersection([1, 1, 2, 3, 4, 5], [1, 1, 3, 5, 7, 9]) AS inter +---------------------------------------------------------+ ``` +### `disjunction()` + +Returns the disjunction (symmetric difference) of two lists: the unique elements +present in exactly one of the lists. The order of the result is not guaranteed. + + +This function is equivalent to **apoc.coll.disjunction**. + + +{

Input:

} + +- `list1: List[Any]` ➡ The first list. +- `list2: List[Any]` ➡ The second list. + +{

Output:

} + +- `List[Any]` ➡ The unique elements found in only one of the two lists. + +{

Usage:

} + +The following query will return the elements present in only one of the lists: + +```cypher +RETURN collections.disjunction([1, 2, 3, 4, 5], [3, 4, 5]) AS disjunction; +``` + +```plaintext ++---------------------------------------------------------+ +| disjunction | ++---------------------------------------------------------+ +| [1, 2] | ++---------------------------------------------------------+ +``` + +### `subtract()` + +Returns the first list as a set with all elements of the second list removed. The +result is deduplicated and its order is not guaranteed. + + +This function is equivalent to **apoc.coll.subtract**. + + +{

Input:

} + +- `list1: List[Any]` ➡ The list to subtract from. +- `list2: List[Any]` ➡ The list of elements to remove. + +{

Output:

} + +- `List[Any]` ➡ The unique elements of the first list that are not present in the second list. + +{

Usage:

} + +The following query will remove the elements of the second list from the first: + +```cypher +RETURN collections.subtract([1, 2, 3, 4, 5, 6, 6], [3, 4, 5]) AS subtracted; +``` + +```plaintext ++---------------------------------------------------------+ +| subtracted | ++---------------------------------------------------------+ +| [1, 2, 6] | ++---------------------------------------------------------+ +``` + +### `duplicates()` + +Returns the values that appear more than once in a list, each reported a single +time, in the order in which the duplicate is first observed. + + +This function is equivalent to **apoc.coll.duplicates**. + + +{

Input:

} + +- `coll: List[Any]` ➡ The input list. + +{

Output:

} + +- `List[Any]` ➡ The values that occur more than once in the input list. + +{

Usage:

} + +The following query will return the values that appear more than once: + +```cypher +RETURN collections.duplicates([1, 1, 2, 3, 3, 3]) AS duplicates; +``` + +```plaintext ++---------------------------------------------------------+ +| duplicates | ++---------------------------------------------------------+ +| [1, 3] | ++---------------------------------------------------------+ +``` + ### `flatten()` Returns flattened list of inputs provided. From b0f64277f102aeaf7645fb361d750decbb288466 Mon Sep 17 00:00:00 2001 From: imilinovic Date: Mon, 20 Jul 2026 17:05:01 +0200 Subject: [PATCH 3/4] docs: List all collections functions in the compatibility table and mark their equivalents Add the compatibility-table rows for the collections functions that were missing (including disjunction, subtract, duplicates) and add the equivalence callout to the function pages that lacked one, so every collections function consistently states its compatibility mapping. --- .../available-algorithms.mdx | 12 ++++++ .../available-algorithms/collections.mdx | 38 ++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/pages/advanced-algorithms/available-algorithms.mdx b/pages/advanced-algorithms/available-algorithms.mdx index 749aa1ea2..a56c74b85 100644 --- a/pages/advanced-algorithms/available-algorithms.mdx +++ b/pages/advanced-algorithms/available-algorithms.mdx @@ -173,6 +173,18 @@ Running `SHOW QUERY CALLABLE MAPPINGS` requires the `CONFIG` privilege. | apoc.coll.toSet | Converts the input list to a set | [collections.to_set()](/advanced-algorithms/available-algorithms/collections#to_set) | | apoc.coll.sum | Calculates the sum of listed elements | [collections.sum()](/advanced-algorithms/available-algorithms/collections#sum) | | apoc.coll.partition | Partitions the input list into sub-lists of the specified size | [collections.partition()](/advanced-algorithms/available-algorithms/collections#partition) | +| apoc.coll.sort | Sorts the elements of an input list of the same data type | [collections.sort()](/advanced-algorithms/available-algorithms/collections#sort) | +| apoc.coll.containsSorted | Verifies the presence of an element in a sorted list | [collections.contains_sorted()](/advanced-algorithms/available-algorithms/collections#contains_sorted) | +| apoc.coll.containsAll | Checks if a list contains all the values from another list | [collections.contains_all()](/advanced-algorithms/available-algorithms/collections#contains_all) | +| apoc.coll.intersection | Returns the unique intersection of two lists | [collections.intersection()](/advanced-algorithms/available-algorithms/collections#intersection) | +| apoc.coll.disjunction | Returns the symmetric difference of two lists (elements in exactly one) | [collections.disjunction()](/advanced-algorithms/available-algorithms/collections#disjunction) | +| apoc.coll.subtract | Returns the first list with the elements of the second removed, deduplicated | [collections.subtract()](/advanced-algorithms/available-algorithms/collections#subtract) | +| apoc.coll.duplicates | Returns the values that appear more than once in a list | [collections.duplicates()](/advanced-algorithms/available-algorithms/collections#duplicates) | +| apoc.coll.sumLongs | Calculates the sum of list elements cast to integers | [collections.sum_longs()](/advanced-algorithms/available-algorithms/collections#sum_longs) | +| apoc.coll.avg | Calculates the average of listed elements | [collections.avg()](/advanced-algorithms/available-algorithms/collections#avg) | +| apoc.coll.max | Returns the maximum-value element of the input list | [collections.max()](/advanced-algorithms/available-algorithms/collections#max) | +| apoc.coll.min | Returns the minimum-value element of the input list | [collections.min()](/advanced-algorithms/available-algorithms/collections#min) | +| apoc.coll.split | Splits the provided list based on a specified delimiter | [collections.split()](/advanced-algorithms/available-algorithms/collections#split) | | apoc.convert.toTree | Converts values into tree structures | [convert_c.to_tree()](/advanced-algorithms/available-algorithms/convert_c#to_tree) | | apoc.convert.fromJsonList | Converts a JSON string representation of a list into an actual list object | [json_util.from_json_list()](/advanced-algorithms/available-algorithms/json_util#from_json_list) | | apoc.convert.toJson | Converts any value to its JSON string representation | [json_util.to_json()](/advanced-algorithms/available-algorithms/json_util#to_json) | diff --git a/pages/advanced-algorithms/available-algorithms/collections.mdx b/pages/advanced-algorithms/available-algorithms/collections.mdx index a85c115bc..cb0ced4b8 100644 --- a/pages/advanced-algorithms/available-algorithms/collections.mdx +++ b/pages/advanced-algorithms/available-algorithms/collections.mdx @@ -82,6 +82,10 @@ RETURN collections.sum(null) AS sum, collections.sort(null) AS sorted; Sorts the elements of an input list if they are of the same data type. For the input list to be sorted, its elements must be comparable and of the same type. + +This function is equivalent to **apoc.coll.sort**. + + {

Input:

} - `coll: List[Any]` ➡ List of elements that need to be sorted. @@ -112,6 +116,10 @@ Verifies the presence of a certain element in a sorted list. If an unsorted list is passed, there is no guarantee that the result will be correct. For the input list to be sorted, its elements must be comparable and of the same type. + +This function is equivalent to **apoc.coll.containsSorted**. + + {

Input:

} - `coll: List[Any]` ➡ The target list where the element is searched for. @@ -277,6 +285,10 @@ RETURN collections.contains([1,2,3], "e") AS output; Checks if a list contains all the values from another list. + +This function is equivalent to **apoc.coll.containsAll**. + + {

Input:

} - `coll: List[Any]` ➡ The target list used for searching values. @@ -308,6 +320,10 @@ RETURN collections.contains_all([1, 2, 3, "pero"], [1, 1, 1, 1, 2, 3]) AS contai Returns the unique intersection of two lists. + +This function is equivalent to **apoc.coll.intersection**. + + {

Input:

} - `first: List[Any]` ➡ The first list. @@ -607,6 +623,10 @@ RETURN collections.sum([1, 2.3, -4, a.id]) AS sum; Calculates the sum of list elements casted to integers. The initial list elements have to be `Numeric` data type, or an exception is thrown. + +This function is equivalent to **apoc.coll.sumLongs**. + + {

Input:

} - `numbers: List[Any]` ➡ The list of numbers. @@ -637,6 +657,10 @@ Calculates the average of listed elements if they are of the same type and can be summed (the elements need to be numerics). Listing elements of different data types, or data types that are impossible to sum, will throw an exception. + +This function is equivalent to **apoc.coll.avg**. + + {

Input:

} - `numbers: List[Any]` ➡ The list of numbers. @@ -665,6 +689,10 @@ RETURN collections.avg([5, 5, 6, 7, -5]) AS average; The procedure returns the element of the maximum value from the input list. + +This function is equivalent to **apoc.coll.max**. + + {

Input:

} - `values: List[Any]` ➡ The input list where an element of the maximum value must be found. @@ -695,6 +723,10 @@ Finds the element of the minimum value in an input list. Listing elements of different data types, or data types that are impossible to compare, will throw an exception. + +This function is equivalent to **apoc.coll.min**. + + {

Input:

} - `values: List[Any]` ➡ The input list where an element of the minimum value must be found. @@ -727,6 +759,10 @@ Splits the provided list based on a specified delimiter. Returns a series of sublists generated by breaking the original list wherever the delimiter is encountered. The delimiter itself is not included in the resulting sublists. + +This procedure is equivalent to **apoc.coll.split**. + + {

Input:

} - `subgraph: Graph` (**OPTIONAL**) ➡ A specific subgraph, which is an [object of type Graph](/advanced-algorithms/run-algorithms#run-procedures-on-subgraph) returned by the `project()` function, on which the algorithm is run. @@ -799,4 +835,4 @@ RETURN result; +---------------------------------------------------------+ | [5,6] | +---------------------------------------------------------+ -``` \ No newline at end of file +``` From 5e233a5e5539a14fcf1cb443402ea407d3f746f9 Mon Sep 17 00:00:00 2001 From: imilinovic Date: Mon, 20 Jul 2026 17:23:36 +0200 Subject: [PATCH 4/4] docs: Include disjunction, subtract, and duplicates in the NULL-handling matrix --- .../available-algorithms/collections.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pages/advanced-algorithms/available-algorithms/collections.mdx b/pages/advanced-algorithms/available-algorithms/collections.mdx index cb0ced4b8..96a6b1254 100644 --- a/pages/advanced-algorithms/available-algorithms/collections.mdx +++ b/pages/advanced-algorithms/available-algorithms/collections.mdx @@ -47,9 +47,9 @@ argument-validation error. Each function returns a defined result: | Function | Result when a list argument is `NULL` | | --- | --- | | `sum()`, `sum_longs()`, `avg()`, `min()`, `max()`, `to_set()`, `pairs()` | `null` | -| `union()`, `union_all()` | the other list; `null` when both are `NULL` | -| `remove_all()` | `null` when the first list is `NULL`; the first list when the second is `NULL` | -| `intersection()`, `sort()`, `flatten()` | empty list `[]` | +| `union()`, `union_all()`, `disjunction()` | the other list; `null` when both are `NULL` | +| `remove_all()`, `subtract()` | `null` when the first list is `NULL`; the first list when the second is `NULL` | +| `intersection()`, `sort()`, `flatten()`, `duplicates()` | empty list `[]` | | `contains()`, `contains_all()`, `contains_sorted()` | `false` | | `frequencies_as_map()` | empty map `{}` | | `split()`, `partition()` | no rows | @@ -60,7 +60,7 @@ argument-validation error. Each function returns a defined result: - `contains()` and `contains_all()` never match a `NULL` search value (`NULL = NULL` is not true), so searching for `NULL` returns `false`. - `split()` treats a `NULL` delimiter as matching nothing and returns the whole list as a single part; `NULL` list elements are kept. - `frequencies_as_map()` counts `NULL` elements under the `"NO_VALUE"` key. -- `flatten()`, `pairs()`, `to_set()`, `union()`, `union_all()`, `remove_all()` and `intersection()` keep `NULL` elements as ordinary values. +- `flatten()`, `pairs()`, `to_set()`, `union()`, `union_all()`, `remove_all()`, `intersection()`, `disjunction()`, `subtract()` and `duplicates()` keep `NULL` elements as ordinary values. - `sum()`, `sum_longs()`, `avg()`, `sort()` and `contains_sorted()` still reject a list that contains a `NULL` element; `contains_sorted()` also rejects a `NULL` search value, and `partition()` still rejects a `NULL` size. For example, a `NULL` argument returns the defined result instead of erroring: