问题描述
在用Cypher完成一个需求时,遇到个尴尬:
需要 CREATE
一个noden
,然后根据情况给n.type
赋予不同值。比如我的场景是LOAD一个文件, 然后根据当前行中某一个字段的不同取值来判断。
期望的代码逻辑如下
LOAD CSV WITH HEADERS FROM "file:///data.csv" AS row
CREATE (c:Car)
SET
IF row.engine = '1'
c.type = 'EV'
ELSE row.engine = '2'
c.type = 'PV'
可是,Cypher没这个用法。
CASE is not enough
唯一能找到的类似的是CASE clause。
如下是一个官方给出的样例:
MATCH (n)
RETURN
CASE
WHEN n.eyes = 'blue'
THEN 1
WHEN n.age < 40
THEN 2
ELSE 3
END AS result
貌似可以,但可惜的是,CASE
只限于返回一个literal的表达式。也就是,无法在THEN
后面放clause。
用其他语言写API,实现逻辑?
是不是我们只能用API去做了?比如用Python driver写个API,用Python语法实现判断逻辑,让Cypher完成最基本的CRUD?
不要放弃,要有专研精神! 我们可以仔细研究下Cypher语言中其他的clause,看看是否有可以利用的。
Researching...
Hack it
Ok,hacking时刻到了。感谢porterhau5的启发。
我们先来看看FOREACH
的用法,看一个官方说明的例子。
MATCH p = (ups)<-[DEPENDS_ON]-(device) WHERE ups.id='EPS-7001'
FOREACH (n IN nodes(p) | SET n.available = FALSE )
能不能把CASE
和FOREACH
结合起来呢?
比如,我们可以利用下FOREACH的机制:
如果
|
左侧的list
为空则右侧的SET n.available = FALSE
不会执行,不为空则执行。而CASE
是可以返回需要的list
的。
聪明的你是不是已经知道如何hacking了?
下面,给大家抛个砖吧。
LOAD CSV WITH HEADERS FROM "file:///data.csv" AS row
CREATE (c:Car)
FOREACH (redcohen in CASE
WHEN row.engine ='1' THEN [1]
ELSE [] END | SET c.type='EV')
FOREACH (redcohen in CASE
WHEN row.engine ='2' THEN [1]
ELSE [] END | SET c.type='PV')
重点的hacking点在哪里呢?
=> 对了,是对FOREACH iteration的准确把握,如果CASE
返回的list
为空[]
,则不执行右侧部分SET ...
,如果返回为list
的size
为1,执行右侧部分一次。
是不是还可以处理更加复杂的逻辑?或者更加elegant? 读者自己去创造吧。
网友评论