2.10. Property Extraction from Multiple Candidate Frames¶
xGT supports extracting properties from variables that can be bound to multiple frames. This is the case for multiple edge traversal steps, when unwinding a path variable into its component path elements, as well as for vertex and edge outputs from whole graph algorithms.
MATCH (:Companies)-[b:CompetesAgainst | :PartneredWith]->(:Companies)
In this example, the variable b
can match an edge instance of the frames CompetesAgainst
or PartneredWith
.
If both of those frames have a name
property then the following constraint is valid:
MATCH (:Companies)-[b:CompetesAgainst | :PartneredWith]->(:Companies)
WHERE b.name STARTS WITH 'M'
This will match edge instances from the CompetesAgainst
or PartneredWith
frames that have names starting with the letter “M”.
For path variables, we must first unwind the path into its components.
MATCH p = ()-[:Edge0 | :Edge1 *1..10]->()
UNWIND p AS elem
RETURN elem.name
Once the path is unwound, we can use the variable introduced by the UNWIND
clause to refer to properties in the frames that are part of the path.
In this example, we are referring to the name
property of the vertex and edge frames involved in the specified path.
CALL breadth_first_search(["Graph__Edge1", "Graph__Edge2"],
{ sources : [id(Graph__Vertex1, "key1")] })
YIELD edge
RETURN edge.id, edge.distance
INTO Results
This example returns the id
and distance
properties of edges that can be from Graph__Edge1
or Graph__Edge2
.
2.10.1. Limitations on Multiple Frame Property Extraction¶
Properties extracted from multiple candidate frames are subject to the following constraints:
A property doesn’t have to exist on all the frames. If a property doesn’t exist on a frame, then it is substituted with the
NULL
value at query execution time.A property must be of the same type or compatible types for all the frames it exists in.
The only compatible types are numerical types: integer and floating point.
If frame A
has a property prop
of type integer and frame B
has a property with the same name of floating-point type, then the following query is well-formed:
MATCH ()-[ab : A | B]->()
WHERE ab.prop > 10
However, if the property of the same name has incompatible types in the candidate frames, then the TQL compiler will reject the query (in this case, the frame Edge0
has a property prop
of text type, while it’s a integer on frame Edge1
):
MATCH p = ()-[:Edge0 | :Edge1 *1..10]->()
UNWIND p AS elem
RETURN elem.prop + 1.0
If a property with that name does not exist on a candidate frame, then it is substituted with the NULL
value at query execution time, allowing the query to run:
MATCH p = (:Person)-[:WorksFor]->(:Company)
UNWIND p AS elem
RETURN elem.first_name
In this example, only the Person
frame has a property first_name
.
The WorksFor
and Company
frames do not have that property, thus the value is substituted with NULL
in the returned rows.