Repository: neo4j/docs-cypher
Pull request #1251: Expression tags
Author: login: JPryce-Aklundh
Labels: name: cherry-pick-this-to-5.x
description: Cherry pick this PR changes to the 5.x branch
Created: 2025-04-25T12:05:17Z | Merged: 2025-04-25T13:17:14Z

Also updates WHERE and UNION (both of which were changed significantly by Expressions project)


Diff:
diff --git a/modules/ROOT/pages/clauses/where.adoc b/modules/ROOT/pages/clauses/where.adoc
index aad77710a..bd5c42260 100644
--- a/modules/ROOT/pages/clauses/where.adoc
+++ b/modules/ROOT/pages/clauses/where.adoc
@@ -43,13 +43,14 @@ CREATE (andy:Swedish:Person {name: 'Andy', age: 36}),
 == Basic filtering
 
 .Filter on a node label
+// tag::clauses_where_node_label[]
 [source, cypher]
 ----
 MATCH (n)
 WHERE n:Swedish
 RETURN n.name AS name
 ----
-// end::clauses_where_in_match_clause[]
+// end::clauses_where_node_label[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -62,12 +63,14 @@ RETURN n.name AS name
 |===
 
 .Filter on a node property
+// tag::clauses_where_node_property[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.age < 35
 RETURN n.name AS name, n.age AS age
 ----
+// end::clauses_where_node_property[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -80,12 +83,14 @@ RETURN n.name AS name, n.age AS age
 |===
 
 .Filter on a relationship property
+// tag::clauses_where_relationship_property[]
 [source, cypher]
 ----
 MATCH (:Person {name:'Andy'})-[k:KNOWS]->(f)
 WHERE k.since < 2000
 RETURN f.name AS oldFriend
 ----
+// end::clauses_where_relationship_property[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -112,12 +117,14 @@ To filter on a property using a dynamically computed name, use square brackets `
 ----
 
 .Filter on a dynamically computed node property
+// tag::clauses_where_dynamic[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n[$propname] > 40
 RETURN n.name AS name, n.age AS age
 ----
+// end::clauses_where_dynamic[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -180,12 +187,14 @@ In this case, `name` is the only variable in scope for the `RETURN` clause.
 === Fixed-length patterns
 
 .`WHERE` inside a node pattern
+// tag::clauses_where_node_pattern[]
 [source, cypher]
 ----
 WITH 35 AS minAge
 MATCH (a:Person WHERE a.name = 'Andy')-[:KNOWS]->(b:Person WHERE b.age > minAge)
 RETURN b.name AS name
 ----
+// end::clauses_where_node_pattern[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -264,13 +273,15 @@ RETURN [(a)-[r:KNOWS WHERE r.since < minYear]->(b:Person) | r.since] AS years
 If matching for variable length patterns, `WHERE` can only be used together with the xref:patterns/variable-length-patterns.adoc#quantified-path-patterns[quantified path pattern] or xref:patterns/variable-length-patterns.adoc#quantified-relationships[quantified relationships] syntax.
 
 .Allowed - `WHERE` predicate inside a quantified relationship
+// tag::clauses_where_var_length[]
 [source, cypher]
 ----
 MATCH p = (a:Person {name: "Andy"})-[r:KNOWS WHERE r.since < 2011]->{1,4}(:Person)
 RETURN [n IN nodes(p) | n.name] AS paths
 ----
+// end::clauses_where_var_length[]
 
-Note that any path´s including `Timothy` and `Susan` are excluded by the `WHERE` predicate, since their incoming `KNOWS` relationships both have a `since` value that is higher than `2011.`
+Note that any paths including `Timothy` and `Susan` are excluded by the `WHERE` predicate, since their incoming `KNOWS` relationships both have a `since` value that is higher than `2011.`
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
diff --git a/modules/ROOT/pages/expressions/conditional-expressions.adoc b/modules/ROOT/pages/expressions/conditional-expressions.adoc
index daf8e2669..d68734489 100644
--- a/modules/ROOT/pages/expressions/conditional-expressions.adoc
+++ b/modules/ROOT/pages/expressions/conditional-expressions.adoc
@@ -75,6 +75,7 @@ END
 [[case-simple-examples]]
 === Example
 
+// tag::expressions_conditional_expressions_simple[]
 [source, cypher]
 ----
 MATCH (n:Person)
@@ -85,6 +86,8 @@ CASE n.eyes
   ELSE 3
 END AS result, n.eyes
 ----
+// end::expressions_conditional_expressions_simple[]
+
 
 [role="queryresult",options="header,footer",cols="2*<m"]
 |===
@@ -148,6 +151,7 @@ END
 [[case-extended-simple-examples]]
 === Example
 
+// tag::expressions_conditional_expressions_extended_simple[]
 [source, cypher]
 ----
 MATCH (n:Person)
@@ -162,6 +166,7 @@ CASE n.age
   ELSE "Adult"
 END AS result
 ----
+// end::expressions_conditional_expressions_extended_simple[]
 
 [role="queryresult",options="header,footer",cols="2*<m"]
 |===
@@ -212,6 +217,7 @@ In this case, the predicate is tested to find a valid alternative.
 [[case-generic-examples]]
 === Example
 
+// tag::expressions_conditional_expressions_generic[]
 [source, cypher]
 ----
 MATCH (n:Person)
@@ -222,6 +228,7 @@ CASE
   ELSE 3
 END AS result, n.eyes, n.age
 ----
+// end::expressions_conditional_expressions_generic[]
 
 [role="queryresult",options="header,footer",cols="3*<m"]
 |===
@@ -299,6 +306,7 @@ For more information about `null`, see xref:values-and-types/working-with-null.a
 
 The results of a `CASE` expression can be used to set properties on a node or relationship.
 
+// tag::expressions_conditional_expressions_properties[]
 [source, cypher]
 ----
 MATCH (n:Person)
@@ -311,6 +319,7 @@ END AS colorCode
 SET n.colorCode = colorCode
 RETURN n.name, n.colorCode
 ----
+// end::expressions_conditional_expressions_properties[]
 
 [role="queryresult",options="header,footer",cols="2*<m"]
 |===
diff --git a/modules/ROOT/pages/expressions/list-expressions.adoc b/modules/ROOT/pages/expressions/list-expressions.adoc
index 90535ac84..2426d776b 100644
--- a/modules/ROOT/pages/expressions/list-expressions.adoc
+++ b/modules/ROOT/pages/expressions/list-expressions.adoc
@@ -41,6 +41,7 @@ The subscript operator, `[]`, can be used to access specific elements in a `LIST
 `[-1]` refers to the last element in a `LIST`, `[-2]` to the penultimate element, and so on.
 
 .Access individual elements in a `LIST`
+// tag::expressions_list_element_access[]
 [source, cypher]
 ----
 WITH [1, 2, 3, 4] AS list
@@ -48,6 +49,7 @@ RETURN list[0] AS firstElement,
        list[2] AS thirdElement,
        list[-1] AS finalElement
 ----
+// end::expressions_list_element_access[]
 
 .Result
 [role="queryresult",options="header,footer",cols="3*<m"]
@@ -87,11 +89,13 @@ RETURN list[$myIndex] AS secondElement
 |===
 
 .Access a `LIST` within a nested `LIST`
+// tag::expressions_list_nested_list_access[]
 [source, cypher]
 ----
 WITH [[1, 2], [3, 4], [5, 6]] AS nestedList
 RETURN nestedList[1] AS secondList
 ----
+// end::expressions_list_nested_list_access[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -104,12 +108,14 @@ RETURN nestedList[1] AS secondList
 |===
 
 .Access specific elements in a nested `LIST`
+// tag::expressions_list_nested_list_specific_element_access[]
 [source, cypher]
 ----
 WITH [[1, 2], [3, 4], [5, 6]] AS nestedList 
 RETURN nestedList[1] AS secondList,
        nestedList[1][0] AS firstElementOfSecondList
 ----
+// end::expressions_list_nested_list_specific_element_access[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -189,6 +195,7 @@ This allows for extracting a subset of a `LIST` rather than a single element.
 List slicing is inclusive at the start of the range, but exclusive at the end (e.g. `list[start..end]` includes `start`, but excludes `end`).
 
 .Slice operations on a `LIST`
+// tag::expressions_list_slicing[]
 [source, cypher]
 ----
 WITH [1, 2, 3, 4, 5, 6] AS list
@@ -196,6 +203,7 @@ RETURN list[2..4] AS middleElements,
        list[..2] AS noLowerBound,
        list[2..] AS noUpperBound
 ----
+// end::expressions_list_slicing[]
 
 .Result
 [role="queryresult",options="header,footer",cols="3*<m"]
@@ -210,6 +218,7 @@ RETURN list[2..4] AS middleElements,
 Negative indexing in list slicing references elements from the end of the `LIST`; `..-1` excludes the last element, `..-2` excludes the last two elements, and so on.
 
 .Negative indexing and list slicing
+// tag::expressions_list_negative_slicing[]
 [source, cypher]
 ----
 WITH [1, 2, 3, 4, 5, 6] AS list
@@ -217,6 +226,7 @@ RETURN list[..-1] AS finalElementRemoved,
        list[..-2] AS finalTwoElementsRemoved,
        list[-3..-1] AS removedFirstThreeAndLast
 ----
+// end::expressions_list_negative_slicing[]
 
 .Result
 [role="queryresult",options="header,footer",cols="3*<m"]
@@ -251,11 +261,13 @@ RETURN nestedList[0..2] AS slicedNestedList
 Slicing inner `LIST` values require two `[]` operators; the first `[]` accesses elements from the outer `LIST`, while the second slices or accesses elements from the inner `LIST`.
 
 .Slice inner `LIST`
+// tag::expressions_list_slice_inner_list[]
 [source, cypher]
 ----
 WITH [[1, 2, 3], [4, 5, 6], [7, 8, 9]] AS nestedList
 RETURN nestedList[1][0..2] AS slicedInnerList
 ----
+// end::expressions_list_slice_inner_list[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -293,11 +305,13 @@ Cypher contains two list concatenation operators: `||` and `+`.
 `||` is xref:appendix/gql-conformance/index.adoc[GQL conformant], while `+` is not.
 
 .List concatenation using `||` and `+`
+// tag::expressions_list_concatenation[]
 [source, cypher]
 ----
 RETURN [1,2] || [3,4] AS list1,
        [1,2] + [3,4] AS list2
 ----
+// end::expressions_list_concatenation[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -353,12 +367,14 @@ The `+` operator can add elements to the beginning or end of a `LIST` value.
 This is not possible using the `||` operator.
 
 .Add elements to the beginning and end of a `LIST`
+// tag::expressions_list_add_elements[]
 [source, cypher]
 ----
 WITH [1, 2, 3, 4] AS list
 RETURN 0 + list AS newBeginning,
        list + 5 AS newEnd
 ----
+// end::expressions_list_add_elements[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -458,11 +474,13 @@ RETURN [x IN range(0,5) | x * 10] AS result
 
 
 .List comprehension with both an expression and filtering
+// tag::expressions_list_comprehension[]
 [source, cypher]
 ----
 WITH [1, 2, 3, 4, 5] AS list
 RETURN [n IN list WHERE n > 2 | n] AS filteredList
 ----
+// end::expressions_list_comprehension[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -498,6 +516,7 @@ RETURN [listIndex IN range(0, size(list)-1) | toString(listIndex) || ': ' || toS
 The below query iterates over the `skills` property of each `Person` node and creates a new `LIST` by xref:expressions/string-operators.adoc[concatenating the `STRING`] `" expert"` to each element in `skills`.
 
 .Modify `LIST` properties using list comprehension
+// tag::expressions_list_comprehension_properties[]
 [source, cypher]
 ----
 MATCH (p:Person) WHERE p.skills IS NOT NULL
@@ -505,6 +524,7 @@ ORDER BY p.name
 RETURN p.name AS name,
       [skill IN p.skills | skill + " expert"] AS modifiedSkills
 ----
+// end::expressions_list_comprehension_properties[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -524,11 +544,13 @@ RETURN p.name AS name,
 The next query uses the xref:functions/aggregating.adoc#functions-collect[`collect()`] function to gather all `Person` nodes into a `LIST`, and the `WHERE 'Python' IN person.skills` predicate filters that list to include only those nodes whose `skills` property contains `Python`.
 
 .List comprehension with a `WHERE` predicate
+// tag::expressions_list_comprehension_where[]
 [source, cypher]
 ----
 MATCH (p:Person)
 RETURN [person IN collect(p) WHERE 'Python' IN person.skills | person.name] AS pythonExperts
 ----
+// end::expressions_list_comprehension_where[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -543,10 +565,12 @@ RETURN [person IN collect(p) WHERE 'Python' IN person.skills | person.name] AS p
 List comprehension can be used to remove any unknown `NULL` values when concatenating `LIST` values.
 
 .List comprehension to remove `NULL` values during list concatenation
+// tag::expressions_list_comprehension_concatenation_remove_null[]
 [source, cypher]
 ----
 RETURN [x IN ([1, null, 3] || [null, 5, null]) WHERE x IS NOT NULL] AS listWithoutNull
 ----
+// end::expressions_list_comprehension_concatenation_remove_null[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -572,11 +596,13 @@ Pattern comprehension is used to create new `LIST` values by matching graph patt
 The below query retrieves a list of names of people who work for `Alice` by using pattern comprehension extract the names of `employees` into a `LIST`.
 
 .Pattern comprehension on a fixed-length pattern
+// tag::expressions_list_pattern_comprehension[]
 [source, cypher]
 ----
 MATCH (alice:Person {name: 'Alice'})
 RETURN [(employee:Person)-[:WORKS_FOR]->(alice) | employee.name] AS employees
 ----
+// end::expressions_list_pattern_comprehension[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -591,11 +617,13 @@ RETURN [(employee:Person)-[:WORKS_FOR]->(alice) | employee.name] AS employees
 Pattern comprehensions can include `WHERE` predicates.
 
 .Pattern comprehension including a `WHERE` predicate
+// tag::expressions_list_pattern_comprehension_where[]
 [source, cypher]
 ----
 MATCH (alice:Person {name: 'Alice'})
 RETURN [(employee:Person)-[:WORKS_FOR]->(alice) WHERE employee.age > 30 | employee.name || ', ' || toString(employee.age)] AS employeesAbove30
 ----
+// end::expressions_list_pattern_comprehension_where[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -622,6 +650,7 @@ The below query uses a pattern comprehension to collect the skills of all superi
 The xref:functions/list.adoc#functions-reduce[`reduce()`] function concatenates these skills into a single `LIST`, and xref:clauses/unwind.adoc[`UNWIND`] is used to flatten this `LIST` before returning the distinct skills in a new `LIST`.
 
 .Allowed: variable-length pattern comprehension using variable-length relationship syntax
+// tag::expressions_list_pattern_comprehension_var_length[]
 [source, cypher]
 ----
 MATCH (cecil:Person {name: 'Cecil'})
@@ -630,6 +659,7 @@ WITH reduce(accumulatedSkills = [], superiorSkills IN allSuperiorsSkills | accum
 UNWIND allSkills AS superiorsSkills
 RETURN collect(DISTINCT superiorsSkills) AS distinctSuperiorsSkills
 ----
+// end::expressions_list_pattern_comprehension_var_length[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
diff --git a/modules/ROOT/pages/expressions/map-expressions.adoc b/modules/ROOT/pages/expressions/map-expressions.adoc
index c0d2ea3a4..2424c1818 100644
--- a/modules/ROOT/pages/expressions/map-expressions.adoc
+++ b/modules/ROOT/pages/expressions/map-expressions.adoc
@@ -52,12 +52,14 @@ Cypher contains two map operators:
 `MAP` values can be accessed statically by specifying a key after the `.` operator.
 
 .Static `MAP` value access
+// tag::expressions_map_static_access[]
 [source, cypher]
 ----
 WITH {a: 10, b: 20, c: 30} AS map
 RETURN map.a AS firstValue,
        map.c AS lastValue
 ----
+// end::expressions_map_static_access[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -73,12 +75,14 @@ To statically access a value in a nested `MAP`, use chained `.` operators.
 Each `.` operator traverses one level deeper into the nested structure.
 
 .Static access of a nested `MAP` value
+// tag::expressions_map_static_access_nested_map[]
 [source, cypher]
 ----
 WITH {a: 10, b: 20, c: 30, innerMap: {x: 100, y: 200, z: 300}} AS map
 RETURN map.a AS firstOuterValue,
        map.innerMap.y AS secondInnerValue
 ----
+// end::expressions_map_static_access_nested_map[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -120,12 +124,14 @@ To dynamically access a `MAP` value, use the subscript operator, `[]`.
 The key can be provided by a variable or a parameter.
 
 .Dynamically access a `MAP` value using a variable
+// tag::expressions_map_dynamic_access[]
 [source, cypher]
 ----
 WITH {a: 10, b: 20, c: 30} AS map,
      'a' AS dynamicKey
 RETURN map[dynamicKey] AS dynamicValue
 ----
+// end::expressions_map_dynamic_access[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -141,7 +147,7 @@ RETURN map[dynamicKey] AS dynamicValue
 [source, parameters]
 ----
 {
-  "dynamicKey" : 'a'
+  "dynamicKey" : "a"
 }
 ----
 
@@ -163,12 +169,14 @@ RETURN map[$dynamicKey] AS dynamicValue
 |===
 
 .Dynamically access a nested `MAP` value
+// tag::expressions_map_dynamic_access_nested_map[]
 [source, cypher]
 ----
 WITH {a: 10, b: 20, c: 30, innerMap: {x: 100, y: 200, z: 300}} AS map,
      'z' AS dynamicInnerKey
 RETURN map.innerMap[dynamicInnerKey] AS dynamicInnerValue
 ----
+// end::expressions_map_dynamic_access_nested_map[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -271,11 +279,13 @@ If `mapVariable` is `NULL`, the projection evaluates to `NULL`.
 Map projections with a key selector are useful when you need to extract specific key-value pairs from a `MAP`.
 
 .Basic example
+// tag::expressions_map_projection_key_selector[]
 [source, cypher]
 ----
 WITH {a: 10, b: 20, c: 30} AS map
 RETURN map{.a, .c} AS projectedMap
 ----
+// end::expressions_map_projection_key_selector[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -315,11 +325,13 @@ RETURN p.name AS actor, collect(m{.title, .released}) AS movies
 Map projections with a literal entry are useful when you want to add custom values to a projected `MAP` value without modifying the original data structure.
 
 .Basic example
+// tag::expressions_map_projection_literal_entry[]
 [source, cypher]
 ----
 WITH {a: 10, b: 20, c: 30} AS map
 RETURN map{a: map.a, valueSum: map.a + map.b + map.c} AS projectedMap
 ----
+// end::expressions_map_projection_literal_entry[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -359,12 +371,14 @@ RETURN keanu {.name, totalMovies: size(movies)} AS keanuDetails
 Map projection with a variable selector is useful when you want to project values based on a variable name.
 
 .Basic example
+// tag::expressions_map_projection_variable_selector[]
 [source, cypher]
 ----
 MATCH (keanu:Person {name: 'Keanu Reeves'})  
 WITH keanu, date('1964-09-02') AS dob, 'Beirut, Lebanon' AS birthPlace
 RETURN keanu{.name, dob, birthPlace} AS projectedKeanu
 ----
+// end::expressions_map_projection_variable_selector[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -406,11 +420,13 @@ RETURN actor{totalMovies, .name} AS nameAndMovies
 Map projection with an all-map projection is useful when you want to project all key-value pairs from a `MAP` without explicitly listing them. 
 
 .Basic example
+// tag::expressions_map_projection_all_map_projection[]
 [source, cypher]
 ----
 WITH {a: 10, b: 20, c: 30} AS map
 RETURN map{.*} AS projectedMap
 ----
+// end::expressions_map_projection_all_map_projection[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
diff --git a/modules/ROOT/pages/expressions/mathematical-operators.adoc b/modules/ROOT/pages/expressions/mathematical-operators.adoc
index c59381969..6c308326e 100644
--- a/modules/ROOT/pages/expressions/mathematical-operators.adoc
+++ b/modules/ROOT/pages/expressions/mathematical-operators.adoc
@@ -21,10 +21,12 @@ For additional mathematical expressions, see:
 == Examples
 
 .Addition operator (`+`)
+// tag::expressions_mathematical_operators_addition[]
 [source, cypher]
 ----
 RETURN 10 + 5 AS result
 ----
+// end::expressions_mathematical_operators_addition[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -54,10 +56,12 @@ RETURN + 5 AS result
 
 
 .Subtraction operator (`-`)
+// tag::expressions_mathematical_operators_subtraction[]
 [source, cypher]
 ----
 RETURN 10 - 5 AS result
 ----
+// end::expressions_mathematical_operators_subtraction[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -86,10 +90,12 @@ RETURN - 5 AS result
 |===
 
 .Multiplication operator (`*`)
+// tag::expressions_mathematical_operators_multiplication[]
 [source, cypher]
 ----
 RETURN 10 * 5 AS result
 ----
+// end::expressions_mathematical_operators_multiplication[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -102,10 +108,12 @@ RETURN 10 * 5 AS result
 |===
 
 .Division operator (`/`)
+// tag::expressions_mathematical_operators_division[]
 [source, cypher]
 ----
 RETURN 10 / 5 AS result
 ----
+// end::expressions_mathematical_operators_division[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -118,10 +126,12 @@ RETURN 10 / 5 AS result
 |===
 
 .Modulo division operator (`%`)
+// tag::expressions_mathematical_operators_modulo_division[]
 [source, cypher]
 ----
 RETURN 10 % 3 AS result
 ----
+// end::expressions_mathematical_operators_modulo_division[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -135,10 +145,12 @@ RETURN 10 % 3 AS result
 
 
 .Exponentiation operator (`^`)
+// tag::expressions_mathematical_operators_exponentiation[]
 [source, cypher]
 ----
 RETURN 10 ^ 5 AS result
 ----
+// end::expressions_mathematical_operators_exponentiation[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
diff --git a/modules/ROOT/pages/expressions/node-relationship-operators.adoc b/modules/ROOT/pages/expressions/node-relationship-operators.adoc
index a17704bfe..b00ed8979 100644
--- a/modules/ROOT/pages/expressions/node-relationship-operators.adoc
+++ b/modules/ROOT/pages/expressions/node-relationship-operators.adoc
@@ -62,6 +62,7 @@ RETURN p.firstName AS name
 |===
 
 .Access node and relationship properties statically
+// tag::expressions_node_relationship_operators_static_property_access[]
 [source, cypher]
 ----
 MATCH (employee:Person)-[r:WORKS_FOR]->(manager:Person)
@@ -69,6 +70,7 @@ RETURN employee.firstName AS employee,
        r.since AS employedSince,
        manager.firstName AS manager
 ----
+// end::expressions_node_relationship_operators_static_property_access[]
 
 .Result
 [role="queryresult",options="header,footer",cols="3*<m"]
@@ -87,12 +89,14 @@ RETURN employee.firstName AS employee,
 Property values can be accessed dynamically by using the subscript operator, `[]`.
 
 .Access properties dynamically using a variable
+// tag::expressions_node_relationship_operators_dynamic_property_access[]
 [source, cypher]
 ----
 WITH 'lastName' AS nodeProperty
 MATCH (p:Person)
 RETURN p[nodeProperty] AS lastName
 ----
+// end::expressions_node_relationship_operators_dynamic_property_access[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -163,12 +167,13 @@ The xref:functions/scalar.adoc#functions-coalesce[`coalesce()`] function can be
 In the below example, it replaces the first `NULL` value found with an empty `STRING`.
 
 .Use the `coalesce()` function to skip `NULL` values
+// tag::expressions_node_relationship_operators_null[]
 [source, cypher]
 ----
 MATCH (p:Person)
 RETURN p.firstName || coalesce(' ' + p.middleName, '') || ' ' || p.lastName AS fullName
 ----
-
+// end::expressions_node_relationship_operators_null[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
diff --git a/modules/ROOT/pages/expressions/predicates/boolean-operators.adoc b/modules/ROOT/pages/expressions/predicates/boolean-operators.adoc
index ae3e46ae8..de86410cf 100644
--- a/modules/ROOT/pages/expressions/predicates/boolean-operators.adoc
+++ b/modules/ROOT/pages/expressions/predicates/boolean-operators.adoc
@@ -50,12 +50,14 @@ CREATE (alice:Person {name:'Alice', age: 65, role: 'Project manager', email: 'al
 =====
 
 .`AND` operator
+// tag::expressions_predicates_boolean_operators_and[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.age > 30 AND n.role = 'Software developer'
 RETURN n.name AS name, n.age AS age, n.role AS role
 ----
+// end::expressions_predicates_boolean_operators_and[]
 
 .Result
 [role="queryresult",options="header,footer",cols="3*<m"]
@@ -68,12 +70,14 @@ RETURN n.name AS name, n.age AS age, n.role AS role
 |===
 
 .`OR` operator
+// tag::expressions_predicates_boolean_operators_or[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.age < 30 OR n.role = 'Software developer'
 RETURN n.name AS name, n.age AS age, n.role AS role
 ----
+// end::expressions_predicates_boolean_operators_or[]
 
 .Result
 [role="queryresult",options="header,footer",cols="3*<m"]
@@ -87,12 +91,14 @@ RETURN n.name AS name, n.age AS age, n.role AS role
 |===
 
 .`XOR` operator
+// tag::expressions_predicates_boolean_operators_xor[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.age > 30 XOR n.role = 'Software developer'
 RETURN n.name AS name, n.age AS age, n.role AS role
 ----
+// end::expressions_predicates_boolean_operators_xor[]
 
 .Result
 [role="queryresult",options="header,footer",cols="3*<m"]
@@ -109,12 +115,14 @@ RETURN n.name AS name, n.age AS age, n.role AS role
 |===
 
 .`NOT` operator
+// tag::expressions_predicates_boolean_operators_not[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE NOT n.age = 39
 RETURN n.name AS name, n.age AS age
 ----
+// end::expressions_predicates_boolean_operators_not[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
diff --git a/modules/ROOT/pages/expressions/predicates/comparison-operators.adoc b/modules/ROOT/pages/expressions/predicates/comparison-operators.adoc
index 64f8ab269..71266bc9f 100644
--- a/modules/ROOT/pages/expressions/predicates/comparison-operators.adoc
+++ b/modules/ROOT/pages/expressions/predicates/comparison-operators.adoc
@@ -44,12 +44,14 @@ CREATE (alice:Person {name:'Alice', age: 65, role: 'Project manager', email: 'al
 =====
 
 .Equality operator (`=`)
+// tag::expressions_predicates_comparison_operators_equality[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.role = 'Software developer'
 RETURN n.name AS name, n.role AS role
 ----
+// end::expressions_predicates_comparison_operators_equality[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -63,12 +65,14 @@ RETURN n.name AS name, n.role AS role
 |===
 
 .Inequality operator (`<>`)
+// tag::expressions_predicates_comparison_operators_inequality[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.role <> 'Software developer'
 RETURN n.name AS name, n.role AS role
 ----
+// end::expressions_predicates_comparison_operators_inequality[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -84,12 +88,14 @@ RETURN n.name AS name, n.role AS role
 |===
 
 .Less than operator (`<`)
+// tag::expressions_predicates_comparison_operators_less_than[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.age < 39
 RETURN n.name AS name, n.age AS age
 ----
+// end::expressions_predicates_comparison_operators_less_than[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -103,12 +109,14 @@ RETURN n.name AS name, n.age AS age
 |===
 
 .Less than or equal operator (`\<=`)
+// tag::expressions_predicates_comparison_operators_less_than_or_equal[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.age <= 39
 RETURN n.name AS name, n.age AS age
 ----
+// end::expressions_predicates_comparison_operators_less_than_or_equal[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -124,12 +132,14 @@ RETURN n.name AS name, n.age AS age
 |===
 
 .Greater than operator (`>`)
+// tag::expressions_predicates_comparison_operators_greater_than[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.age > 39
 RETURN n.name AS name, n.age AS age
 ----
+// end::expressions_predicates_comparison_operators_greater_than[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -143,12 +153,14 @@ RETURN n.name AS name, n.age AS age
 |===
 
 .Greater than or equal operator (`>=`)
+// tag::expressions_predicates_comparison_operators_greater_than_or_equal[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.age >= 39
 RETURN n.name AS name, n.age AS age
 ----
+// end::expressions_predicates_comparison_operators_greater_than_or_equal[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -164,12 +176,14 @@ RETURN n.name AS name, n.age AS age
 |===
 
 .`IS NULL` operator
+// tag::expressions_predicates_comparison_operators_is_null[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.email IS NULL
 RETURN n.name AS name
 ----
+// end::expressions_predicates_comparison_operators_is_null[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -184,12 +198,14 @@ RETURN n.name AS name
 |===
 
 .`IS NOT NULL` operator
+// tag::expressions_predicates_comparison_operators_is_not_null[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.email IS NOT NULL
 RETURN n.name AS name, n.email AS email
 ----
+// end::expressions_predicates_comparison_operators_is_not_null[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
diff --git a/modules/ROOT/pages/expressions/predicates/list-operators.adoc b/modules/ROOT/pages/expressions/predicates/list-operators.adoc
index 0f1d9365d..78bd021c8 100644
--- a/modules/ROOT/pages/expressions/predicates/list-operators.adoc
+++ b/modules/ROOT/pages/expressions/predicates/list-operators.adoc
@@ -37,12 +37,14 @@ CREATE (alice:Person {name:'Alice', age: 65, role: 'Project manager', email: 'al
 =====
 
 .`IN` operator
+// tag::expressions_predicates_list_operators_in[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.role IN ['Software developer', 'Project manager']
 RETURN n.name AS name, n.role AS role
 ----
+// end::expressions_predicates_list_operators_in[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -157,10 +159,12 @@ RETURN NULL IN [1, 2, NULL] AS nullInList, 123 IN NULL AS valueInNull
 To check if `NULL` is a member of a `LIST`, use the xref:functions/predicate.adoc#functions-any[`any()`] function:
 
 .Checking if `NULL` is a member of a `LIST`
+// tag::expressions_predicates_list_operators_check_null[]
 [source, cypher]
 ----
 RETURN any(x IN [1, 2, NULL] WHERE x IS NULL) AS containsNull
 ----
+// end::expressions_predicates_list_operators_check_null[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -196,10 +200,12 @@ RETURN [0, 2] IN [[1, 2], [3, 4]] AS listInNestedList
 
 
 .Checking for membership in nested `LIST` values
+// tag::expressions_predicates_list_operators_nested_list[]
 [source, cypher]
 ----
 RETURN [3, 4] IN [[1, 2], [3, 4]] AS listInNestedList
 ----
+// end::expressions_predicates_list_operators_nested_list[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -235,11 +241,13 @@ A subset check verifies if all elements of one `LIST` exist in another.
 The xref:functions/predicate.adoc#functions-all[`all()`] function is used to ensure that every element in the first `LIST` is found in the second `LIST`.
 
 .Subset check
+// tag::expressions_predicates_list_operators_list_subset[]
 [source, cypher]
 ----
 WITH [1,3,4] AS sub, [3,5,1,7,6,2,8,4] AS list
 RETURN all(x IN sub WHERE x IN list) AS subInList
 ----
+// end::expressions_predicates_list_operators_list_subset[]
 
 This returns `TRUE` because all elements in `sub` are part of `list`.
 
diff --git a/modules/ROOT/pages/expressions/predicates/path-pattern-expressions.adoc b/modules/ROOT/pages/expressions/predicates/path-pattern-expressions.adoc
index b484bc791..fdaf6f85f 100644
--- a/modules/ROOT/pages/expressions/predicates/path-pattern-expressions.adoc
+++ b/modules/ROOT/pages/expressions/predicates/path-pattern-expressions.adoc
@@ -45,12 +45,14 @@ CREATE (alice:Person {name:'Alice', age: 65, role: 'Project manager'}),
 == Examples
 
 .Simple path pattern expression
+// tag::expressions_predicates_path_pattern_expression[]
 [source, cypher]
 ----
 MATCH (employee:Person)
 WHERE (employee)-[:WORKS_FOR]->(:Person {name: 'Alice'})
 RETURN employee.name AS employee
 ----
+// end::expressions_predicates_path_pattern_expression[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -64,12 +66,14 @@ RETURN employee.name AS employee
 |===
 
 .Path pattern expression including boolean operators `NOT` and `AND`
+// tag::expressions_predicates_path_pattern_expression_boolean[]
 [source, cypher]
 ----
 MATCH (employee:Person)
 WHERE NOT employee.name = 'Cecil' AND (employee)-[:WORKS_FOR]->(:Person {name: 'Alice'})
 RETURN employee.name AS employee
 ----
+// end::expressions_predicates_path_pattern_expression_boolean[]
 
 
 .Result
diff --git a/modules/ROOT/pages/expressions/predicates/string-operators.adoc b/modules/ROOT/pages/expressions/predicates/string-operators.adoc
index 3cc6a7c96..8ad3e7d09 100644
--- a/modules/ROOT/pages/expressions/predicates/string-operators.adoc
+++ b/modules/ROOT/pages/expressions/predicates/string-operators.adoc
@@ -40,13 +40,14 @@ CREATE (alice:Person {name:'Alice', age: 65, role: 'Project manager', email: 'al
 =====
 
 .`STARTS WITH` operator
+// tag::expressions_predicates_string_operators_prefix[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.name STARTS WITH 'C'
 RETURN n.name AS name
 ----
-
+// end::expressions_predicates_string_operators_prefix[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -61,12 +62,14 @@ RETURN n.name AS name
 |===
 
 .`ENDS WITH` operator
+// tag::expressions_predicates_string_operators_suffix[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.role ENDS WITH 'developer'
 RETURN n.name AS name, n.role AS role
 ----
+// end::expressions_predicates_string_operators_suffix[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -80,13 +83,14 @@ RETURN n.name AS name, n.role AS role
 |===
 
 .`CONTAINS` operator
+// tag::expressions_predicates_string_operators_substring[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.role CONTAINS 'eng'
 RETURN n.name AS name, n.role AS role
 ----
-
+// end::expressions_predicates_string_operators_substring[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -112,12 +116,14 @@ Flags are given at the beginning of the regular expression.
 =====
 
 .Regular expression (`=~`)
+// tag::expressions_predicates_string_operators_regex[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.email =~ '.*@company.com'
 RETURN n.name AS name, n.email AS email
 ----
+// end::expressions_predicates_string_operators_regex[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -133,13 +139,15 @@ RETURN n.name AS name, n.email AS email
 
 By pre-pending a regular expression with the flag `(?i)`, the whole expression becomes case-insensitive:
 
-.Case-insensitive regular expression `(?i)` 
+.Case-insensitive regular expression `(?i)`
+// tag::expressions_predicates_string_operators_regex_flag[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.name =~ '(?i)CEC.*'
 RETURN n.name
 ----
+// end::expressions_predicates_string_operators_regex_flag[]
 
 The names of both `Cecil` and `Cecilia` are returned because their name starts with `'CEC'` regardless of casing:
 
@@ -229,10 +237,12 @@ For more information, see the documentation for link:https://unicode.org/reports
 ====
 
 .`IS NORMALIZED` operator
+// tag::expressions_predicates_string_operators_is_normalized[]
 [source, cypher]
 ----
 RETURN 'the \u212B char' IS NORMALIZED AS normalized
 ----
+// end::expressions_predicates_string_operators_is_normalized[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -253,10 +263,12 @@ For example, `RETURN 1 IS NORMALIZED` returns `NULL`.
 The `IS NOT NORMALIZED` operator is used to check whether the given `STRING` is not in the `NFC` Unicode normalization form:
 
 .`IS NOT NORMALIZED`
+// tag::expressions_predicates_string_operators_is_not_normalized[]
 [source, cypher]
 ----
 RETURN 'the \u212B char' IS NOT NORMALIZED AS notNormalized
 ----
+// end::expressions_predicates_string_operators_is_not_normalized[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -286,12 +298,14 @@ The available normalization types are:
 * `NFKD`
 
 .Query
+// tag::expressions_predicates_string_operators_is_normalized_normalization_type[]
 [source, cypher]
 ----
 WITH 'the \u00E4 char' as myString
 RETURN myString IS NFC NORMALIZED AS nfcNormalized,
     myString IS NFD NORMALIZED AS nfdNormalized
 ----
+// end::expressions_predicates_string_operators_is_normalized_normalization_type[]
 
 The given `STRING` contains the Unicode character: `\u00E4`, which is considered normalized in `NFC` form, but not in `NFD` form.
 
diff --git a/modules/ROOT/pages/expressions/predicates/type-predicate-expressions.adoc b/modules/ROOT/pages/expressions/predicates/type-predicate-expressions.adoc
index 4c638554f..ef8c60bd2 100644
--- a/modules/ROOT/pages/expressions/predicates/type-predicate-expressions.adoc
+++ b/modules/ROOT/pages/expressions/predicates/type-predicate-expressions.adoc
@@ -18,11 +18,13 @@ For all available Cypher types, see the section on xref::values-and-types/proper
 [[type-predicate-regular]]
 == Verify the type of a Cypher expression
 
+// tag::expressions_predicates_type_predicate[]
 [source, cypher]
 ----
 UNWIND [42, true, 'abc', NULL] AS val
 RETURN val, val IS :: INTEGER AS isInteger
 ----
+// end::expressions_predicates_type_predicate[]
 
 [role="queryresult",options="header,footer",cols="2*<m"]
 |===
@@ -41,11 +43,13 @@ RETURN val, val IS :: INTEGER AS isInteger
 
 It is also possible to verify that a Cypher expression is not of a certain type, using the negated type predicate expression `IS NOT ::`.
 
+// tag::expressions_predicates_type_predicate_not[]
 [source, cypher]
 ----
 UNWIND [42, true, 'abc', NULL] AS val
 RETURN val, val IS NOT :: STRING AS notString
 ----
+// end::expressions_predicates_type_predicate_not[]
 
 [role="queryresult",options="header,footer",cols="2*<m"]
 |===
@@ -67,12 +71,14 @@ All Cypher types includes the `NULL` value.
 Since Neo4j 5.10, type predicate expressions can be appended with `NOT NULL`.
 This means that `IS ::` returns `TRUE` for all expressions evaluating to `NULL`, unless `NOT NULL` is appended.
 
+// tag::expressions_predicates_type_predicate_null[]
 [source, cypher]
 ----
 RETURN
   NULL IS :: BOOLEAN AS isBoolean,
   NULL IS :: BOOLEAN NOT NULL AS isNotNullBoolean
 ----
+// end::expressions_predicates_type_predicate_null[]
 
 [role="queryresult",options="header,footer",cols="2*<m"]
 |===
@@ -154,12 +160,14 @@ image::type_predicate_expression_graph.svg[]
 
 The following query finds all `Person` nodes with an `age` property that is an `INTEGER` with a value greater than `18`.
 
+// tag::expressions_predicates_type_predicate_properties[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.age IS :: INTEGER AND n.age > 18
 RETURN n.name AS name, n.age AS age
 ----
+// end::expressions_predicates_type_predicate_properties[]
 
 [role="queryresult",options="header,footer",cols="2*<m"]
 |===
@@ -247,11 +255,13 @@ RETURN 42 IS :: ANY AS isOfTypeAny, 42 IS :: NOTHING AS isOfTypeNothing
 
 Closed dynamic union types allow for the testing of multiple types in the same predicate.
 
+// tag::expressions_predicates_type_predicate_closed_dynamic_union[]
 [source, cypher]
 ----
 UNWIND [42, 42.0, "42"] as val
 RETURN val, val IS :: INTEGER | FLOAT AS isNumber
 ----
+// end::expressions_predicates_type_predicate_closed_dynamic_union[]
 
 [role="queryresult",options="header,footer",cols="2*<m"]
 |===
diff --git a/modules/ROOT/pages/expressions/string-operators.adoc b/modules/ROOT/pages/expressions/string-operators.adoc
index 2ea6e8105..270ce87d4 100644
--- a/modules/ROOT/pages/expressions/string-operators.adoc
+++ b/modules/ROOT/pages/expressions/string-operators.adoc
@@ -16,11 +16,13 @@ For additional expressions that evaluate to `STRING` values, see xref:functions/
 == Examples
 
 .`||` and `+`
+// tag::expressions_string_concatenation_basic[]
 [source, cypher]
 ----
 RETURN 'Neo' || '4j' AS result1,
        'Neo' + '4j' AS result2
 ----
+// end::expressions_string_concatenation_basic[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -53,11 +55,13 @@ RETURN 'The number is: ' || toString(42) AS result
 Cypher does not insert spaces when concatenating `STRING` values.
 
 .Adding whitespaces in `STRING` concatenation
+// tag::expressions_string_concatenation_whitespace[]
 [source, cypher]
 ----
 RETURN 'Alpha' || 'Beta' AS result1, 
        'Alpha' || ' ' || 'Beta' AS result2
 ----
+// end::expressions_string_concatenation_whitespace[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -70,12 +74,14 @@ RETURN 'Alpha' || 'Beta' AS result1,
 |===
 
 .Concatenating `STRING` properties
+// tag::expressions_string_concatenation_properties[]
 [source, cypher]
 ----
 CREATE (p:Person {firstName: 'Keanu', lastName: 'Reeves'})
 SET p.fullName = p.firstName || ' ' || p.lastName
 RETURN p.fullName AS fullName
 ----
+// end::expressions_string_concatenation_properties[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -104,10 +110,12 @@ RETURN 'Hello' || ', ' || 'World' AS result
 |===
 
 .Adding prefix, suffix, and separators in `STRING` concatenation
+// tag::expressions_string_concatenation_prefix_suffix_separator[]
 [source, cypher]
 ----
 RETURN 'My favorite fruits are: ' || 'apples' || ', ' || 'bananas' || ', and ' || 'oranges' || '.' AS result
 ----
+// end::expressions_string_concatenation_prefix_suffix_separator[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -125,11 +133,13 @@ RETURN 'My favorite fruits are: ' || 'apples' || ', ' || 'bananas' || ', and ' |
 `STRING` values in a `LIST` can be concatenated using the xref:functions/list.adoc#functions-reduce[`reduce()`] function.
 
 .Concatenate `STRING` values in a `LIST`
+// tag::expressions_string_concatenation_concatenate_strings_in_list[]
 [source, cypher]
 ----
 WITH ['Neo', '4j'] AS list
 RETURN reduce(acc = '', item IN list| acc || item) AS result
 ----
+// end::expressions_string_concatenation_concatenate_strings_in_list[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -168,11 +178,13 @@ In the following query, `coalesce()` is used with `reduce()` to replace each `NU
 This ensures that all `NULL` values are effectively skipped, allowing the `reduce()` function to concatenate the remaining `STRING` values.
 
 .Using `reduce()` and `coalesce()` to skip `NULL` values when concatenating a `LIST`
+// tag::expressions_string_concatenation_concatenate_skip_null[]
 [source, cypher]
 ----
 WITH ['Apples', NULL, 'Bananas', NULL, 'Oranges', NULL] AS list
 RETURN 'My favorite fruits are: ' || reduce(acc = head(list), item IN tail(list) | acc || coalesce(', ' || item, '')) || '.' AS result
 ----
+// end::expressions_string_concatenation_concatenate_skip_null[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
@@ -209,11 +221,13 @@ RETURN 'My favorite fruits are: ' || coalesce(reduce(acc = head(list), item IN t
 Additionally, xref:expressions/list-expressions.adoc#list-comprehension[list comprehension] allows concatenating a `STRING` value to each item in a `LIST` to generate a new `LIST` of modified `STRING` values.
 
 .List comprehension with `STRING` concatenation on `LIST` items
+// tag::expressions_string_concatenation_concatenate_list_comprehension[]
 [source, cypher]
 ----
 WITH ['Apples', 'Bananas', 'Oranges'] AS list 
 RETURN [item IN list | 'Eat more ' || item || '!'] AS result
 ----
+// end::expressions_string_concatenation_concatenate_list_comprehension[]
 
 .Result
 [role="queryresult",options="header,footer",cols="1*<m"]
diff --git a/modules/ROOT/pages/expressions/temporal-operators.adoc b/modules/ROOT/pages/expressions/temporal-operators.adoc
index dd1b09e29..d266bbd94 100644
--- a/modules/ROOT/pages/expressions/temporal-operators.adoc
+++ b/modules/ROOT/pages/expressions/temporal-operators.adoc
@@ -68,6 +68,7 @@ For additional expressions that evaluate to a xref:values-and-types/temporal.ado
 In the below example, the xref:functions/temporal/index.adoc#functions-localdatetime[`localdatetime()`] function is used to create a `LOCAL DATETIME` value, and the xref:functions/temporal/duration.adoc#functions-durations[`duration()`] function is used to create a `DURATION` value.
 
 .Add and subtract a `DURATION` value to/from a `LOCAL DATETIME`
+// tag::expressions_temporal_operators_add_duration_to_instant[]
 [source, cypher]
 ----
 WITH localdatetime({year:1984, month:10, day:11, hour:12, minute:31, second:14}) AS aDateTime,
@@ -75,6 +76,7 @@ WITH localdatetime({year:1984, month:10, day:11, hour:12, minute:31, second:14})
 RETURN aDateTime + aDuration AS addition,
       aDateTime - aDuration AS subtraction
 ----
+// end::expressions_temporal_operators_add_duration_to_instant[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]
@@ -162,6 +164,7 @@ If the result of the division does not fit into the original components, it over
 This overflow also occurs when multiplying with fractions.
 
 .Multiply and divide a `DURATION` value
+// tag::expressions_temporal_operators_multiply_divide_duration[]
 [source, cypher]
 ----
 WITH duration({days: 14, minutes: 12, seconds: 70, nanoseconds: 1}) AS aDuration
@@ -169,6 +172,7 @@ RETURN aDuration,
        aDuration * 2 AS multipliedDuration,
        aDuration / 3 AS dividedDuration
 ----
+// end::expressions_temporal_operators_multiply_divide_duration[]
 
 .Result
 [role="queryresult",options="header,footer",cols="3*<m"]
diff --git a/modules/ROOT/pages/queries/combined-queries.adoc b/modules/ROOT/pages/queries/combined-queries.adoc
index f1cafcadc..05e8a2892 100644
--- a/modules/ROOT/pages/queries/combined-queries.adoc
+++ b/modules/ROOT/pages/queries/combined-queries.adoc
@@ -45,7 +45,7 @@ CREATE (johnny:Actor {name: 'Johnny Depp'}),
 Combining the results from two queries is done using `UNION ALL`.
 
 .Query
-// tag::clauses_union_all[]
+// tag::combined_queries_union_all[]
 [source, cypher]
 ----
 MATCH (n:Actor)
@@ -54,7 +54,7 @@ UNION ALL
 MATCH (n:Movie)
 RETURN n.title AS name
 ----
-// end::clauses_union_all[]
+// end::combined_queries_union_all[]
 
 The combined result is returned, including duplicates.
 
@@ -76,7 +76,7 @@ The combined result is returned, including duplicates.
 By not including `ALL` in the `UNION`, duplicates are removed from the combined result set.
 
 .Query
-// tag::clauses_union[]
+// tag::combined_queries_union[]
 [source, cypher]
 ----
 MATCH (n:Actor)
@@ -85,7 +85,7 @@ UNION
 MATCH (n:Movie)
 RETURN n.title AS name
 ----
-// end::clauses_union[]
+// end::combined_queries_union[]
 
 The combined result is returned, without duplicates.
 
@@ -141,6 +141,7 @@ If you are using an older version of Neo4j, use `CALL { ... }` instead.
 For more information, see xref:subqueries/call-subquery.adoc#import-variables[CALL subqueries -> Importing variables].
 
 .Query
+// tag::combined_queries_post_union_processing[]
 [source, cypher]
 ----
 CALL () { 
@@ -153,6 +154,7 @@ UNION ALL
 RETURN name, count(*) AS count
 ORDER BY count
 ----
+// end::combined_queries_post_union_processing[]
 
 .Result
 [role="queryresult",options="header,footer",cols="2*<m"]


Reviews:
user: login: rsill-neo4j
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-25T12:26:28Z
user: login: JPryce-Aklundh
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-25T12:30:04Z
user: login: rsill-neo4j
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-25T12:49:26Z
user: login: rsill-neo4j
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-25T12:58:30Z
user: login: rsill-neo4j
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-25T13:02:21Z
user: login: rsill-neo4j
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-25T13:14:19Z

Review comments:
diff_hunk: @@ -133,13 +139,15 @@ RETURN n.name AS name, n.email AS email
 
 By pre-pending a regular expression with the flag `(?i)`, the whole expression becomes case-insensitive:
 
-.Case-insensitive regular expression `(?i)` 
+.Case-insensitive regular expression `(?i)`
path: modules/ROOT/pages/expressions/predicates/string-operators.adoc
user: login: rsill-neo4j
body: what's the change here?
created_at: 2025-04-25T12:26:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -133,13 +139,15 @@ RETURN n.name AS name, n.email AS email
 
 By pre-pending a regular expression with the flag `(?i)`, the whole expression becomes case-insensitive:
 
-.Case-insensitive regular expression `(?i)` 
+.Case-insensitive regular expression `(?i)`
path: modules/ROOT/pages/expressions/predicates/string-operators.adoc
user: login: JPryce-Aklundh
body: removed accidental whitespace
created_at: 2025-04-25T12:30:04Z
author_association: COLLABORATOR
diff_hunk: @@ -164,12 +176,14 @@ RETURN n.name AS name, n.age AS age
 |===
 
 .`IS NULL` operator
+// tag::expressions_predicates_comparison_operators_is_null[]
 [source, cypher]
 ----
 MATCH (n:Person)
 WHERE n.email IS NULL
 RETURN n.name AS name
 ----
+// end::expressions_predicates_comparison_operators_is_not_null[]
path: modules/ROOT/pages/expressions/predicates/comparison-operators.adoc
user: login: rsill-neo4j
body: ```suggestion
// end::expressions_predicates_comparison_operators_is_null[]
```
created_at: 2025-04-25T12:49:25Z
author_association: CONTRIBUTOR
diff_hunk: @@ -622,6 +650,7 @@ The below query uses a pattern comprehension to collect the skills of all superi
 The xref:functions/list.adoc#functions-reduce[`reduce()`] function concatenates these skills into a single `LIST`, and xref:clauses/unwind.adoc[`UNWIND`] is used to flatten this `LIST` before returning the distinct skills in a new `LIST`.
 
 .Allowed: variable-length pattern comprehension using variable-length relationship syntax
+// tag::expressions_list_pattern_comprehension_var_length[]
path: modules/ROOT/pages/expressions/list-expressions.adoc
user: login: rsill-neo4j
body: this one and contains lines that are so long that they don't render nicely in the cheat sheet :thinking: 
it's a minor thing (formatting)
created_at: 2025-04-25T12:58:30Z
author_association: CONTRIBUTOR
diff_hunk: @@ -168,11 +178,13 @@ In the following query, `coalesce()` is used with `reduce()` to replace each `NU
 This ensures that all `NULL` values are effectively skipped, allowing the `reduce()` function to concatenate the remaining `STRING` values.
 
 .Using `reduce()` and `coalesce()` to skip `NULL` values when concatenating a `LIST`
+// tag::expressions_string_concatenation_concatenate_skip_null[]
path: modules/ROOT/pages/expressions/string-operators.adoc
user: login: rsill-neo4j
body: same here, doesn't format too nicely in the cheat sheet

edit: ok there are a couple more occurrences, won't list them all :)
created_at: 2025-04-25T13:02:21Z
author_association: CONTRIBUTOR

PR comments:
user: login: neo4j-docops-agent
created_at: 2025-04-25T12:51:34Z
body: Thanks for the documentation updates.

The preview documentation has now been torn down - reopening this PR will republish it.
<!-- Sticky Pull Request Commentdocs-pr-changes -->
author_association: COLLABORATOR