尝试缩短基于CASE的谓词失败

时间:2017-11-27 05:55:03

标签: neo4j cypher

这是受到这两个SO线程的启发:

Boolean value return from Neo4j cypher query without CASE

How to set property name and value on csv load?

我有一个包含3列的CSV:

如first_name,prop_name,请将prop_value

约翰,体重,100

保罗,高度,200

约翰,hair_color,金发

保罗,重量,120

所以,有很多人,他们的属性随机分散在不同的行中。我的目标是筛选行并将所有找到的属性分配给其持有者。为简单起见,我们只关注'权重'属性。

我确实知道如何让这项工作做得很好:

    LOAD CSV WITH HEADERS FROM
    "file:///test.csv" AS line
    WITH line
    MERGE (m:Person {name:line.first_name})
    WITH line, CASE line.prop_name WHEN "weight" THEN [1] ELSE [] END as loopW 
    UNWIND loopW as w
    MATCH (p:Person {name: line.first_name})
    SET p.weight = line.prop_value

但是,我试图用更短的版本替换CASE行

    WITH line, collect(line.prop_name = "weight") as loopW 

...这导致了奇怪的行为,创建的节点确实将其“权重”键分配给了,但有时会使用错误的值。所以,我可以看到像(:人{重量:蓝色})

之类的东西

什么是摆脱CASE的正确方法?

1 个答案:

答案 0 :(得分:0)

您应该知道您当前的使用情况会过滤掉所有没有“重量”的线路。作为prop_name(空集合的UNWIND消除了所有其他行,并且它们不会被处理)。

您真正需要的是在节点上设置动态命名属性的更好方法,这样您就可以完全避免使用CASE。

如果您可以安装APOC Procedures(请阅读顶部的说明,了解如何修改neo4j.conf以将程序列入白名单,并注意版本矩阵以确保您获得与您的版本对应的版本Neo4j版本)有一个非常适合您尝试做的事情:CALL apoc.create.setProperty( [node,id,ids,nodes], key, value) YIELD node

用法如下:

LOAD CSV WITH HEADERS FROM
"file:///test.csv" AS line
MERGE (m:Person {name:line.first_name})
CALL apoc.create.setProperty(m, line.prop_name, line.prop_value) YIELD node
RETURN count(distinct m)

修改

扩展原始查询的错误:

UNWIND以乘法方式生成行,相对于集合中的元素数量。如果行中的集合有5个元素,则单行将产生5行,每个元素对应一行。如果集合为空,则将删除该行,因为集合中的任何元素都不能输出行。因此,查询中的任何其他WITH line, CASE ...行都不会有任何好处。

让我们通过示例输入csv来分析原始查询:

LOAD CSV WITH HEADERS FROM
"file:///test.csv" AS line
WITH line  //redundant, line not needed
MERGE (m:Person {name:line.first_name}) // 4 rows corresponding with 2 nodes
WITH line, CASE line.prop_name WHEN "weight" THEN [1] ELSE [] END as loopW 
// still 4 rows, 2 have [1] as loopW, the other 2 have [] as loopW
UNWIND loopW as w // 2 rows eliminated by unwinding empty collections
MATCH (p:Person {name: line.first_name})
SET p.weight = line.prop_value
// only 2 rows are for 'John,weight,100' and 'Paul,weight,120'
// any further repetitions of WITH line, CASE ... UNWIND for different props will fail and eliminate the remaining 2 rows.