在计算Cypher中的属性时,Reduce函数似乎关闭1

时间:2016-09-03 05:51:19

标签: neo4j cypher

我有一个csv文件here,它曾使用本文底部的命令读入Neo4J,创建了一组4个家谱。

对于所有家庭,我想为family_id ='1'的有2个或更多人的家庭返回is_ill

当我查看先验时,我可以很容易地看到我的预期结果是什么,只需在excel中快速过滤以仅显示is_ill ='1'的节点。

enter image description here

你可以看到,对于fam1,fam2和fam4,is_ill ='1'有8,3和3次出现。所以,如果我正确地写了我的查询,我希望得到3 family_id

所以,我已经准备好练习一些Cypher了。这就是我所拥有的:

MATCH p=(:Person)-[]->(:Person)
WHERE 2 <= REDUCE(s = 0, x IN NODES(p) | CASE WHEN x.is_ill = '1' THEN s + 1 ELSE s END)
WITH p
RETURN distinct([x IN nodes(p) | x.family_id][0]) as Family_ID
;

这看起来很棒。除了我意识到它返回了大量的子图,我必须使用这个hacky distinct()和索引[0]。这让我感到紧张,但我永远不知道什么时候或者不是一个好主意进行完整的图遍历,以及当Cypher要返回一大堆子图时。

但我离题了。我的问题的关键在于,由于某种原因,此查询仅返回

| Family_ID |
|-----------|
| fam2      |

如何?我清楚地要求它计算完整路径有多少次具有该属性的节点。关键是2 <= ...。这正是我想要的!而且,如果Cypher返回fam2 ...为什么不归fam3?他们的财产发生次数相同!

如果我将其更改为1 <= ...,我可以四处寻找并获得我想要的结果。为什么这样做?计数是一个??

由于某种原因,s = 0是否应该以不同方式编入索引?这似乎不太可能。也许我的初始MATCH p=(:Person)-[]->(:Person)正在低估目标,我错过了节点?我也不这么认为。 REDUCE的应用方式一定存在问题。

//LOAD UP THE CSV
LOAD CSV WITH HEADERS FROM
'file:///...neo_test2_00.csv' AS line
CREATE (
person:Person {
 date_of_birth: line.`date_of_birth`
,does_forget: line.`does_forget`
,family_id: line.`family_id`
,father_person_id: line.`father_person_id`
,first_name: line.`first_name`
,gender: line.`gender`
,is_ill: line.`is_ill`
,is_proband: line.`is_proband`
,last_name: line.`last_name`
,mother_person_id: line.`mother_person_id`
,pidn: line.`pidn`
,subject_person_id: line.`subject_person_id`
}
)

// create parent relationship for mother
MATCH (m:Person),(s:Person)
  WHERE
(
m.family_id = s.family_id
AND
m.subject_person_id = s.mother_person_id
)
CREATE (m)-[:PARENT_OF]->(s)
;

// create parent relationship for father
MATCH (f:Person),(s:Person)
  WHERE
(
f.family_id = s.family_id
AND
f.subject_person_id = s.father_person_id
)
CREATE (f)-[:PARENT_OF]->(s)
;

1 个答案:

答案 0 :(得分:2)

为什么不使用聚合?

MATCH (p:Person {is_ill: '1'})
WITH p.family_id AS familyId, 
     COUNT(p) AS illCount WHERE illCount >= 2
RETURN familyId, 
       illCount

P.S。您的查询会返回两个ill人的模式。看看这个查询:

MATCH p=(:Person {is_ill:'1'})-[]->(:Person {is_ill:'1'})
RETURN p