neo4j / neo4j

Graphs for Everyone
http://neo4j.com
GNU General Public License v3.0
13.5k stars 2.39k forks source link

Destructuring assignment using `WITH ... AS` Pretty Please! #13516

Open na-wapf opened 3 months ago

na-wapf commented 3 months ago

Feature request

Please consider adding de-structuring assignment to the Cypher language.

Problem

[...]
WITH
   something      as A,
   something_else as B
WITH
  CASE WHEN lookup_result.direction="AB" THEN A ELSE B END as A,
  CASE WHEN lookup_result.direction="AB" THEN B ELSE A END as B,
[...]

This code involves a lot of duplication, particularly in cases where more than two items must be re-arranged.

If the predicate expression is long, this case-based approach requires it to be repeated which is not fun.

In my use case, business logic dictates a small set of valid arrangements therefore sorting methods are not a nice solution.

Proposed solution: Destructuring Assignment

Allow a list of variables to appear on the right hand side of AS:

[...]
WITH
   something      as A,
   something_else as B
WITH
  CASE WHEN lookup_result.direction="AB" THEN [A,B] ELSE [B,A] END as [A,B]
[...]

Prior Art

Cypher's Own :param

Cypher already has something like this syntax for Map objects with the :param directive;

:param [{dateFrom, dateTo, excludePersonNodes}] => {return datetime()-duration({days:65}) as dateFrom, datetime() as dateTo, true as excludePersonNodes}

I don't know if this arrow operator => is permitted elsewhere in the language?

(I often prefer :param over :params because I it seems to be more flexible in terms of dynamically generating values...)

Python's Destructuring assignment

Python has this kind of assignment

a = "something"
b = "somthing_else"

a,b = b,a

Javascript's Destructuring assignment

Javascript has a similar thing

var a = "something";
var b = "somthing_else";

var [a,b] = [b,a];

Many thanks for your time! :)

mnd999 commented 3 months ago

Thanks, I will pass this on to the product team

mnd999 commented 3 months ago

You can do something like this already, it's not quite as nice but it's a little less typing:

WITH CASE WHEN condition THEN [A, B] ELSE [B, A] END AS C
WITH C[0] AS A, C[1] AS B
na-wapf commented 3 months ago

You can do something like this already, it's not quite as nice but it's a little less typing:

WITH CASE WHEN condition THEN [A, B] ELSE [B, A] END AS C
WITH C[0] AS A, C[1] AS B

Thank you for this suggestion :) At least the predicate only appears once in this solution. But it is a lot harder to read!