简体   繁体   中英

Neo4j cypher query ORDER BY with parameters

I have a simple cypher query and would like to modify it with parameters.

MATCH (u:User) WHERE u.email = {searchString} return u ORDER BY {sortField} {sortOrder} SKIP {skipNumber} LIMIT {limitNumber}

Executing this query results in the following error:

Invalid input '{': expected whitespace, comment, '.', node labels, '[', "=~", IN, STARTS, ENDS, CONTAINS, IS, '^', '*', '/', '%', '+', '-', '=', "<>", "!=", '<', '>', "<=", ">=", AND, XOR, OR, DESCENDING, DESC, ASCENDING, ASC, ',', SKIP, LIMIT, LOAD CSV, START, MATCH, UNWIND, MERGE, CREATE, SET, DELETE, REMOVE, FOREACH, WITH, CALL, RETURN, UNION, ';' or end of input (line 1, column 87 (offset: 86)) "MATCH (lc:LeadContact) WHERE lc.email = {searchString} return lc ORDER BY {sortField} {sortOrder} SKIP {skipNumber} LIMIT {limitNumber}"

If I remove "{sortField} {sortOrder}" and write static text (eg, "ORDER by u.name ASC" the query executes smoothly:

MATCH (u:User) WHERE u.email = {searchString} return u ORDER BY u.name ASC SKIP {skipNumber} LIMIT {limitNumber}

Why does cypher not allow parameters here? Or am I doing something wrong?

A different ORDER BY or direction might require a different query plan. Currently you can only parameterize stuff that has no impact on the query plan. Because of the very same reason labels and relationship types are not parameterizable.

Something that can be done is ORDER BY field[$parameter] using dynamic properties as seen in this reply on a similar question.

Now, supposing that you have a query a little bit more complex, with two MATCH statements: if you need to also change the sort field, you could write something like this:

MATCH (u:User)
MATCH (v:Vehicle)
WHERE u.email = {searchString}

WITH coalesce(
  CASE WHEN {sortField} = "u.name" THEN u.name ELSE null END,
  CASE WHEN {sortField} = "v.brand" THEN v.brand ELSE null END,
  u.name // Provide a default sorting field
) AS orderField

RETURN u, v
ORDER BY orderField ASC SKIP {skipNumber} LIMIT {limitNumber}

As for the sorting order, you could use this neat little trick:

ORDER BY
CASE WHEN {sortOrder} = "ASC" THEN orderField ELSE null END ASC,
CASE WHEN {sortOrder} = "ASC" THEN null ELSE orderField END DESC

Of course, this comparison could be made easier to read if {sortOrder} was a boolean, something like {ascending} .

You can do it as follows, taking advantage of the fact that you can parametrise the return:

RETURN a,b,c,b[$sortField] AS sortField
ORDER BY sortField

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM