Parameters, Value
CASE is a user-defined function which maps every row of data in a data stream to a new value, and all the new values have the same structure type.
If data do not come from homologous columns: when used in WITH,
case
will first make a Cartesian Product Combination of all columns and its homologous columns before mapping; when used in RETURN,case
will trim all columns and their homologous columns before mapping.
Syntax:
- Format:
case
when<condition1>
then<projection1>
when<condition2>
then<projection2>
...
else<other>
end - Parameters:(see table below)
- Value:ATTR、ARRAY、TABLE
Name | Category | Specification | Description |
---|---|---|---|
<condition> |
filter | The braces should be removed from the filter | Judgement condition |
<projection> |
NODE、EDGE、PATH、ATTR、ARRAY、TABLE | / | The mapped value satisfying the judgement conditions |
<other> |
NODE、EDGE、PATH、ATTR、ARRAY、TABLE | Not mandatory; 0, empty string, etc. by default | The mapped value not satisfying any judgement conditions in a row |
The mapped value of data in every row with different types of <projection>
and <other>
:
Type | Mapped Value |
---|---|
NODE | Nodes' UUID in the row |
EDGE | Edges' UUID in the row |
PATH | ROW INDEX(starting from 0)in the row |
ATTR | ATTR |
ARRAY | ARRAY |
TABLE | TABLE |
Start to judge every data in a row from the first
<condition>
, output the mapped value once judge condition is satisfied and stop judge the conditions following.
- Abbreviated format: if all
<conditions>
are used to judge if a certain unified expression<uFormat>
equals with other expressions<format1>
,<format2>
,... ,then the function can be put in this way:
case<uFormat>
when<format1>
then<projection1>
when<format2>
then<projection2>
...
else<other>
end
Constant
Example: divide @customer nodes into 4 age groups based on birth years: 1980s, 1990s, and 2000s, count the number of people in each age group
find().nodes({@customer}) as nodes
with CASE
when year(nodes.birthday) <=> [1980, 1989] then "1980s"
when year(nodes.birthday) <=> [1990, 1999] then "1990s"
when year(nodes.birthday) <=> [2000, 2009] then "2000s"
else "others" END as ageGroup
group by ageGroup
return ageGroup, count(ageGroup)
Example: abbreviate the example above
find().nodes({@customer}) as nodes
with CASE floor(year(nodes.birthday)/10)
when 198 then "1980s"
when 199 then "1990s"
when 200 then "2000s"
else "others" END as ageGroup
group by ageGroup
return ageGroup, count(ageGroup)
Function
Example: calculate the actual monthly paydays in 2022, with 15th each month as planned payday and payday will be put off to the nearest Monday if it is a non-workday.
uncollect ["2022-1-15 0:0:0","2022-2-15 0:0:0","2022-3-15 0:0:0","2022-4-15 0:0:0","2022-5-15 0:0:0","2022-6-15 0:0:0","2022-7-15 0:0:0","2022-8-15 0:0:0","2022-9-15 0:0:0","2022-10-15 0:0:0","2022-11-15 0:0:0","2022-12-15 0:0:0"] as plan
return CASE day_of_week(plan)
when 1 then date_add(plan, 1, "day")
when 7 then date_add(plan, 2, "day")
else date_add(plan, 0, "day")
END
Analysis: the first condition in case
adds 1 day to a planned payday that happens to be a Sunday, the second condition adds 2 days to a planned payday on Saturday , ELSE keeps the planned payday as it is by adding 0 day. Note: ELSE can not be followed by plan, for plan's structure type is string, date_add() can only be filled with time, so to keep data structure type consistent plan should be transformed to a time format.
Alias
Example: find one 1-step path from each card CA001, CA002, and CA005, count each path as [<transferCardID>, <amount>,<receivercardID>]; if a path do not exist, count it as [<CardID>, 0, "none"]
find().nodes({_id in ["CA001","CA002","CA005"]}) as cards
optional n(cards).le({@transfer} as e).n({@card} as n).limit(1)
return CASE n
when 0 then [cards._id, 0, "none"]
else [cards._id, e.amount, n._id] END
Analysis: 1) when using optional
, if one of the template query does not return result, then conduct a psyeudo-path 0-0-0; 2)use 'CASE' to find the psyeudo-path 0-0-0 and map it as [<CardID>, 0, "none"], map the rest of paths as a table [<TransferorCardID>,<amount>,<ReceiverCardID>], note that data type should be consistent in each column.