The k-hop template clause khop().n()...n() utilizes a path template to query for k-hop neighbors of the start nodes in the paths.
With the defined path template, the value of k depends on the shortest distance between two nodes, same as explained in the k-hop clause. Additionally, the returned nodes must satisfy the condition set for the destination nodes in the path template.
K-Hop | K-Hop Template | |
|---|---|---|
| Start nodes | Single | Single or multiple |
| Filtering rules for edges | All the same | Can be different |
| Filtering rules for nodes other than the start nodes | All the same | Can be different |
While achieving the same query function, the K-Hop template generally offers better performance than the path template.
For example, the two UQLs return the same results - the number of distinct ads clicked by a user. It's important to note that the destination nodes returned by the path template are not automatically deduplicated, whereas the results of the k-hop template are deduplicated.
UQL// Path Template n({_id == "u316591"}).e({@clicks}).n({@ad} as ads) return count(DISTINCT ads) // K-Hop Template khop().n({_id == "u316591"}).e({@clicks}).n({@ad}) as ads with count(ads)
n() must have a valid filter which can specify multiple nodes.[<steps>] in multi-edge templates e()[<steps>] and e().nf()[<steps>] don't support the format of [*:N], as the k-hop query automatically traverses through the shortest paths.prev_n, prev_e) or custom alias.Method | Param Type | Param Spec | Required | Description | Alias |
|---|---|---|---|---|---|
limit() | Integer | ≥-1 | No | Number of k-hop neighbors to return for each start node (note that not each subquery), -1 signifies returning all | N/A |

Run these UQLs row by row in an empty graphset to create this graph:
UQLcreate().node_schema("country").node_schema("movie").node_schema("director").node_schema("actor").edge_schema("filmedIn").edge_schema("direct").edge_schema("cast").edge_schema("bornIn") create().node_property(@*, "name")Click to expand
Find the 2-hop neighbors of each country that can be reached through a certain path.
UQLkhop().n({@country} as a).le({@filmedIn}).n({@movie}).le({@direct}).n({@director}) as b return table(a.name, b.name)
Result:
| a.name | b.name |
|---|---|
| USA | James Cameron |
| France | James Cameron |
| France | Luc Besson |
Find the 1- and 2-hop neighbors of each country that can be reached through a certain path.
UQLkhop().n({@country} as a).e({!@direct})[:2].n({!@country}) as b return table(a.name, b.name)
Result:
| a.name | b.name |
|---|---|
| USA | Zoe Saldaña |
| USA | The Terminator |
| USA | Avatar |
| France | The Terminator |
| France | Léon |
Find the 2-hop @director neighbors of each country.
UQLkhop().n({@country} as a).e()[2].n({@director}) as b return table(a.name, b.name)
Result:
| a.name | b.name |
|---|---|
| USA | James Cameron |
| France | James Cameron |
| France | Luc Besson |
Find the 2-hop @country neighbors of one actor.
UQLkhop().n({@actor.name == "Zoe Saldaña"}).e()[2].n({@country}) as a return a
Result: No return data.
Even though there exists a 2-step path from the actor to a country (Zoe Saldaña - [@cast] - Avatar - [filmedIn]- USA), that's not the shortest path (Zoe Saldaña - [@bornIn] - USA) between them.
Find one 1-hop neighbor for each director that can be reached through a certain path.
UQLkhop().n({@director} as a).e({@direct}).n().limit(1) as b return table(a.name, b.name)
Result:
| a.name | b.name |
|---|---|
| James Cameron | The Terminator |
| Luc Besson | Léon |
Find the 2-hop @actor neighbors of each country that can be reached through a certain path. Return null if no neighbors are found.
UQLfind().nodes({@country}) as cty optional khop().n(cty).e({!@bornIn})[2].n({@actor}) as actor return table(cty.name, actor.name)
Result:
| cty._id | actor._id |
|---|---|
| France | null |
| USA | Zoe Saldaña |