:meta-keywords: coradb graph, graph functions, database graph, relationships, nodes, path functions, path_comp, path comprehension :meta-description: CoraDB graph functions for working with graph paths, vertices, and edges in MATCH queries. :tocdepth: 3 .. _graph-fn: **************** Graph Functions **************** .. contents:: :depth: 1 :local: Overview ======== Graph functions are used to extract information from graph paths when querying graph data using MATCH clauses. These functions operate on path variables to retrieve vertices, edges, and their properties. The main graph functions are: * **relationships()** - Returns a list of edges in a path * **nodes()** - Returns a list of vertices in a path * **path_comp()** - Performs path comprehension to extract and transform data from graph patterns These functions are typically used in combination with: * :ref:`list_comp() ` - For list comprehensions to process edges/vertices * :ref:`property_of() ` - To extract specific properties from edges or vertices * :ref:`first() ` - To get the first element from a list * :ref:`last() ` - To get the last element from a list .. _fn-nodes: NODES ===== .. function:: nodes(path_variable) The **nodes()** function returns a list of all vertices in a graph path. This function can only be used with path variables from MATCH clauses. :param path_variable: A path variable from a MATCH clause (e.g., pth in MATCH pth=(v1)-[e]->(v2)) :rtype: LIST of vertices .. note:: The **nodes()** function requires exactly one argument, which must be a path variable. It cannot accept NULL, scalars, lists, or non-path variables. Basic Usage Examples -------------------- **Example 1: Get first and last nodes in paths of length 2 or 3** First, let's set up the test data: .. code-block:: sql CREATE EDGE TABLE Knows ( id INT NOT NULL AUTO_INCREMENT, source INT, destination INT, remark STRING ); CREATE VERTEX TABLE Person ( id INT, firstName STRING, lastName STRING, age INT ); INSERT VERTEX INTO Person VALUES (0, 'Jerry', 'Madonna', 10); INSERT VERTEX INTO Person VALUES (1, 'John', 'Doe', 20); INSERT VERTEX INTO Person VALUES (2, 'Alice', 'Johnson', 40); INSERT VERTEX INTO Person VALUES (3, NULL, NULL, NULL); INSERT EDGE FROM (SELECT Person FROM Person WHERE id = 0) TO (SELECT Person FROM Person WHERE id = 1) INTO Knows VALUES (1, 0, 1, 'best friend'); INSERT EDGE FROM (SELECT Person FROM Person WHERE id = 1) TO (SELECT Person FROM Person WHERE id = 2) INTO Knows VALUES (2, 1, 2, 'worst friend'); INSERT EDGE FROM (SELECT Person FROM Person WHERE id = 2) TO (SELECT Person FROM Person WHERE id = 0) INTO Knows VALUES (3, 2, 0, 'most hated'); INSERT EDGE FROM (SELECT Person FROM Person WHERE id = 2) TO (SELECT Person FROM Person WHERE id = 1) INTO Knows VALUES (4, 2, 1, 'close friend'); INSERT EDGE FROM (SELECT Person FROM Person WHERE id = 0) TO (SELECT Person FROM Person WHERE id = 3) INTO Knows VALUES (5, 0, 3, 'distant friend'); Now, collect node IDs in paths of length 2 or 3: .. code-block:: sql SELECT property_of(first(nodes(pth)), lastName, Person) AS first_node, property_of(last(nodes(pth)), lastName, Person) AS last_node FROM MATCH pth=(p1:Person)-[k:Knows {2,3}]->(p2:Person) ORDER BY first_node, last_node; This query extracts all vertices from paths of length 2 or 3, then uses the **first()** and **last()** functions to get the first and last nodes' lastName property. **Example 2: First and last node in reversed path** .. code-block:: sql SELECT property_of(first(nodes(pth)), lastName, Person) AS first_node, property_of(last(nodes(pth)), lastName, Person) AS last_node FROM MATCH pth=(p1:Person)<-[k:Knows {1,2}]-(p2:Person) ORDER BY first_node, last_node; This query finds paths with edges going in the reverse direction (using `<-` instead of `->`) and extracts the first and last node names. **Example 3: Filter paths containing a specific person** .. code-block:: sql SELECT property_of(first(nodes(pth)), lastName, Person) AS first_node FROM MATCH pth=(p1:Person)-[k:Knows {1,3}]->(p2:Person) WHERE 3 IN list_comp(n IN nodes(pth) | property_of(n, id, Person)) ORDER BY first_node; This query finds paths of length 1-3 and filters for those that include a person with ID 3. The **nodes()** function is used within a list comprehension to extract all node IDs in the path. Error Conditions ---------------- The **nodes()** function will return an error in the following cases: **Error 1: Non-path variable argument** .. code-block:: sql SELECT nodes(p1) FROM MATCH pth=(p1:Person)-[k:Knows {1,3}]->(p2:Person); This is invalid because `p1` is a vertex variable, not a path variable. Only path variables (like `pth`) can be passed to **nodes()**. **Error 2: Scalar or NULL argument** .. code-block:: sql SELECT nodes(1) FROM MATCH pth=(p1:Person)-[k:Knows {1,3}]->(p2:Person); This is invalid because **nodes()** requires a path variable, not a scalar value or NULL. See Also -------- * :ref:`relationships() ` - Returns a list of edges in a path * :ref:`path_comp() ` - Performs path comprehension to extract data from graph patterns * :ref:`property_of() ` - Extracts a property value from a vertex or edge * :ref:`list_comp() ` - Performs list comprehension operations * :ref:`first() ` - Returns the first element of a list * :ref:`last() ` - Returns the last element of a list * :ref:`tail() ` - Returns all elements except the first from a sequence * :ref:`at() ` - Returns the element at a specific index in a sequence * :ref:`size() ` - Returns the number of elements in a sequence * :ref:`range() ` - Generates a sequence of integers within a range * :ref:`reduce() ` - Reduces a sequence to a single value using an accumulator * MATCH clause - For graph pattern matching queries .. _fn-relationships: RELATIONSHIPS ============= .. function:: relationships(path_variable) The **relationships()** function returns a list of all edges in a graph path. This function can only be used with path variables from MATCH clauses. :param path_variable: A path variable from a MATCH clause (e.g., pth in MATCH pth=(v1)-[e]->(v2)) :rtype: LIST of edges .. note:: The **relationships()** function requires exactly one argument, which must be a path variable. It cannot accept NULL, scalars, lists, or non-path variables. Basic Usage Examples -------------------- **Example 1: Collect edge IDs in paths of length 2 or 3** Using the same test data setup as in the :ref:`nodes() ` examples above, find paths of length 2 or 3 and collect the edge IDs: .. code-block:: sql SELECT list_comp(e IN relationships(pth) | property_of(e, id, Knows)) AS edge_ids FROM MATCH pth=(p1:Person)-[k:Knows {2,3}]->(p2:Person) ORDER BY edge_ids; This query extracts all edges from paths of length 2 or 3, then uses list comprehension to get the ID of each edge. **Example 2: Reversed path traversal** .. code-block:: sql SELECT list_comp(e IN relationships(pth) | property_of(e, id, Knows)) AS edge_ids FROM MATCH pth=(p1:Person)<-[k:Knows {1,2}]-(p2:Person) ORDER BY edge_ids; This query finds paths with edges going in the reverse direction (using `<-` instead of `->`). **Example 3: Filtering paths by edge properties** .. code-block:: sql SELECT property_of(first(relationships(pth)), id, Knows) AS edge_id FROM MATCH pth=(p1:Person)-[k:Knows {1,3}]->(p2:Person) WHERE 2 IN list_comp(e IN relationships(pth) | property_of(e, id, Knows)) ORDER BY edge_id; This query finds paths of length 1-3 and filters for those that include an edge with ID 2. Error Conditions ---------------- The **relationships()** function will return an error in the following cases: **Error 1: Non-path variable argument** .. code-block:: sql SELECT relationships(p1) FROM MATCH pth=(p1:Person)-[k:Knows {1,3}]->(p2:Person); This is invalid because `p1` is a vertex variable, not a path variable. Only path variables (like `pth`) can be passed to **relationships()**. **Error 2: Scalar or NULL argument** .. code-block:: sql SELECT relationships(1) FROM MATCH pth=(p1:Person)-[k:Knows {1,3}]->(p2:Person); This is invalid because **relationships()** requires a path variable, not a scalar value or NULL. See Also -------- * :ref:`nodes() ` - Returns a list of vertices in a path * :ref:`path_comp() ` - Performs path comprehension to extract data from graph patterns * :ref:`property_of() ` - Extracts a property value from a vertex or edge * :ref:`list_comp() ` - Performs list comprehension operations * :ref:`first() ` - Returns the first element of a list * :ref:`last() ` - Returns the last element of a list * :ref:`tail() ` - Returns all elements except the first from a sequence * :ref:`at() ` - Returns the element at a specific index in a sequence * :ref:`size() ` - Returns the number of elements in a sequence * :ref:`range() ` - Generates a sequence of integers within a range * :ref:`reduce() ` - Reduces a sequence to a single value using an accumulator * MATCH clause - For graph pattern matching queries .. _fn-path-comp: PATH_COMP ========= .. function:: path_comp(pattern [WHERE condition] | expression [ORDER BY ordering]) The **path_comp()** function performs path comprehension on graph patterns, allowing you to extract and transform data from matched paths. It's similar to list comprehension but operates directly on graph patterns. :param pattern: One or more graph patterns to match (e.g., (a:Person)->(b:Person)) :param condition: Optional WHERE clause to filter matched paths :param expression: Expression to evaluate for each matched path (e.g., a.name) :param ordering: Optional ORDER BY clause to sort results :rtype: LIST of values .. note:: The **path_comp()** function allows you to specify graph patterns inline and extract data from vertices and edges without explicitly using MATCH clauses. Basic Usage Examples -------------------- **Example 1: Simple path comprehension** Using the same test data setup as in the :ref:`nodes() ` examples above, extract names from a simple pattern: .. code-block:: sql SELECT path_comp((a:Person)->(b:Person) | a.firstName); This returns the first names of all vertices that have outgoing edges to other Person vertices. **Example 2: Path comprehension with named edges** .. code-block:: sql SELECT path_comp((a:Person)-[e:Knows]->(b:Person) | a.firstName); This is similar to Example 1 but explicitly names the edge variable and specifies the edge label. **Example 3: Path comprehension with ORDER BY** .. code-block:: sql SELECT path_comp((a:Person)-[e:Knows]->(b:Person) | a.firstName ORDER BY 1); This returns first names sorted in ascending order (ORDER BY 1 means order by the first column). **Example 4: Path comprehension with explicit column ordering** .. code-block:: sql SELECT path_comp((a:Person)-[e:Knows]->(b:Person) | a.firstName ORDER BY a.firstName ASC); This explicitly orders by the firstName attribute in ascending order. **Example 5: Filtering by vertex property with WHERE** .. code-block:: sql SELECT path_comp((a:Person)->(b:Person) WHERE a.firstName > 'Alex' | a.firstName); This filters paths where the source vertex has firstName greater than 'Alex'. Error Conditions ---------------- The **path_comp()** function will return an error in the following cases: **Error 1: Missing expression after pipe** .. code-block:: sql SELECT path_comp((a:Person)->(b:Person) | ); This is invalid because the expression after the pipe operator is required. **Error 2: Invalid pattern syntax** .. code-block:: sql SELECT path_comp(a:Person | a.firstName); This is invalid because the pattern must include relationship specification (e.g., `(a:Person)->(b:Person)`). See Also -------- * :ref:`relationships() ` - Returns a list of edges in a path * :ref:`nodes() ` - Returns a list of vertices in a path * :ref:`list_comp() ` - Performs list comprehension operations * :ref:`property_of() ` - Extracts a property value from a vertex or edge * :ref:`first() ` - Returns the first element of a list * :ref:`last() ` - Returns the last element of a list * :ref:`at() ` - Returns the element at a specific index in a sequence * :ref:`reduce() ` - Reduces a sequence to a single value using an accumulator * MATCH clause - For graph pattern matching queries