Neo4j 以过程方式开发密码查询
我一直在研究家谱图 我想回答一个简单的问题: 归还任何Neo4j 以过程方式开发密码查询,neo4j,cypher,family-tree,Neo4j,Cypher,Family Tree,我一直在研究家谱图 我想回答一个简单的问题: 归还任何 有3个或3个以上已识别的成员 谁死了 他们的家庭成员大多是左撇子(至少50%) 我模拟了两个族,其中一个满足标准,另一个不满足标准(问题末尾的代码) 大家庭符合标准。小家庭没有。(旁注:我将定义节点放在每个族上,以便于区分它们,并在匹配时只返回一个族) 我想我已经找到了解决方案的某些部分,但我不知道如何以一种内聚的方式将它们粘在一起 例如(感谢@Tim Kuehn and),我可以找到满足以下条件的返回树:有3个人患有老年痴呆症: M
- 有3个或3个以上已识别的成员
- 谁死了
- 他们的家庭成员大多是左撇子(至少50%)李>
MATCH (f:Family)<-[:FAMILY]-(person:Person)
WHERE person.Diagnosis = "Alzheimers"
WITH f, count(person) AS Count
WHERE Count > 2
// Then report the family members as a single collection
MATCH (a:Person)-[r1:FAMILY]-(f)
RETURN collect(DISTINCT a)
我还可以计算出有多少人是左撇子:
MATCH (f:Family)<-[:FAMILY]-(person:Person)
WHERE person.Handedness = 'Left'
WITH f, count(person) AS Count
RETURN Count
匹配(f:族)(aSP),
(b) -[:CHILD]->(a),
(b) -[:CHILD]->(aSP),
(b) -[:配偶]->(bSP),
(bSib)-[:同级]->(b),
(bSib)-[:子级]->(aSP),
(c) -[:CHILD]->(b),
(c) -[:CHILD]->(bSP),
(cSib)-[:兄弟姐妹]->(c),
(cSib)-[:子级]->(bSP)
//第二个族:族ID=B。此族不符合标准
创造
(a2:Person{姓名:'a2',身份证:'8',性别:'Mean',诊断:'Alzheimers','Is Alive?'Yes',利手:'Right','Risk Score':'PURPLE'}),
(aSP2:Person{name:'aSP2',id:'9',性别:'femal',诊断:'Normal','Is live?'No',利手:'Left','Risk Score':'GIRAFFE'}),
(b2:Person{姓名:'b2',身份证:'10',性别:'Mean',诊断:'Normal','Is Alive','No',利手:'Left','Risk Score':'PURPLE')
创造
(a2)-[:配偶]->(aSP2),
(b2)-[:CHILD]->(a2),
(b2)-[:子级]->(aSP2)
//为第一个族创建定义节点:
创造
(famA:Family{Family_ID:'A'})
和法玛
匹配(a:Person{name:“a”})-[*]-(b:Person)
合并(famA:Family)您可以通过一系列过滤器链接引用以获得最终答案。要获得字段上不同函数的计数,必须重复查询(我发现这很不幸——应该有一种方法可以从单个图形结果中计算多个项)
在下面的例子中,我根据阿尔茨海默氏症病例的数量获得一个家庭参考,然后在查询的其余部分使用该参考来统计人群,然后在最后报告结论
最终结果看起来是这样的:
// Find the families with 2 or more Alzheimers cases
MATCH (fam:Family)<-[:FAMILY]-(person:Person)
WHERE person.Diagnosis = "Alzheimers"
WITH fam, count(person) AS fAlzCount
WHERE fAlzCount > 2
with fam
// Count the # of left-handed family members
MATCH (fam)-[:FAMILY]-(person:Person)
WHERE person.Handedness = 'Left'
WITH fam, count(person) AS LeftCount
// Count the total # of family members
MATCH (fam)-[:FAMILY]-(person:Person)
WITH fam, LeftCount, count(person) AS AllCount
// and then filter for families where more than 1/2 are left-handed
// tofloat() is used to convert the integer results so we can test
// against a float at the end
WHERE tofloat(LeftCount) / tofloat(AllCount) > 0.5
RETURN fam, LeftCount, AllCount
//查找有2个或更多阿尔茨海默病病例的家庭
配对(家庭:家庭)2
和fam
//数一数左撇子家庭成员的人数
匹配(fam)-[:家庭]-(个人:个人)
其中person.handeady=‘Left’
使用fam,将(个人)计数为LeftCount
//计算家庭成员总数
匹配(fam)-[:家庭]-(个人:个人)
使用fam、LeftCount、count(person)作为AllCount
//然后过滤超过1/2的左手族
//tofloat()用于转换整数结果,以便进行测试
//靠着最后的浮子
其中tofloat(LeftCount)/tofloat(AllCount)>0.5
返回fam、LeftCount、AllCount
我认为-这就是您需要的:
MATCH (Family:Family)<-[r:FAMILY]-(Person:Person)
WITH
Family, collect(Person) as F
WITH
Family, size(F) as sF, F,
filter(x in F where x.Handedness='Left') as LH,
filter(x in F where x.Diagnosis="Alzheimers" AND x.`Is Alive?`='No') as AD
WHERE
(size(LH) >= sF/2) AND (size(AD) >= 3)
RETURN Family,
F as wholeFamily,
extract(n IN AD | n.name) as whoAD,
size(LH) as sLH, size(AD) as sAD
匹配(族:族)=sF/2)和(尺寸(AD)>=3)
回归家庭,
F作为整个家庭,
摘录(n在AD | n.名称中)为whoAD,
尺寸(左侧)为sLH,尺寸(AD)为sAD
起初,extract
的语法让我很反感,但现在我发现
更像一个管道,而不是一个bool'or'。这是一段很棒的代码…给人留下深刻印象,非常感谢!有趣的是--首先,您匹配了一个模式,然后用with
部分花了一些时间进行过滤,然后返回到WHERE
子句中匹配模式…在执行此操作时,使用从with
中带出的派生值。非常酷。我如何才能从确定身份节点返回整个家庭?我试图将Person
带到末尾,然后返回,但出现了错误。@MonicaHeddneck Pass和return F(收集家庭成员)-请参阅更新。
// First family: family_ID = A. This family has 3 members with Alzheimers who are not alive, and more than half of them are Left handed
CREATE
( a:Person {name: 'a', id:'1', Gender:'Male', Diagnosis: 'Alzheimers', `Is Alive?`: 'No', Handedness: 'Left', `Risk Score`: 'PURPLE'}),
( aSP:Person {name: 'aSP', id:'2', Gender:'Female', Diagnosis: 'Alzheimers', `Is Alive?`: 'No', Handedness: 'Left', `Risk Score`: 'GIRAFFE'}),
( b:Person {name: 'b', id:'3', Gender:'Male', Diagnosis: 'Normal', `Is Alive?`: 'No', Handedness: 'Left', `Risk Score`: 'PURPLE'}),
( bSP:Person {name: 'bSP', id:'4', Gender:'Female', Diagnosis: 'Alzheimers', `Is Alive?`: 'No', Handedness: 'Right', `Risk Score`: 'GIRAFFE'}),
(bSib:Person {name: 'bSib', id:'5', Gender:'Female', Diagnosis: 'MCI', `Is Alive?`: 'No', Handedness: 'Left', `Risk Score`: 'GIRAFFE'}),
( c:Person {name: 'c', id:'6', Gender:'Male', Diagnosis: 'MCI', `Is Alive?`: 'No', Handedness: 'Right', `Risk Score`: 'PURPLE'}),
(cSib:Person {name: 'cSib', id:'7', Gender:'Female', Diagnosis: 'Alzheimers', `Is Alive?`: 'Yes', Handedness: 'Left', `Risk Score`: 'GIRAFFE'})
CREATE
(a)-[:SPOUSE]->(aSP),
(b)-[:CHILD]->(a),
(b)-[:CHILD]->(aSP),
(b)-[:SPOUSE]->(bSP),
(bSib)-[:SIBLING]->(b),
(bSib)-[:CHILD]->(aSP),
(c)-[:CHILD]->(b),
(c)-[:CHILD]->(bSP),
(cSib)-[:SIBLING]->(c),
(cSib)-[:CHILD]->(bSP)
// Second family: family_ID = B. This family does not meet the criteria
CREATE
( a2:Person {name: 'a2', id:'8', Gender:'Male', Diagnosis: 'Alzheimers', `Is Alive?`: 'Yes', Handedness: 'Right', `Risk Score`: 'PURPLE'}),
( aSP2:Person {name: 'aSP2', id:'9', Gender:'Female', Diagnosis: 'Normal', `Is Alive?`: 'No', Handedness: 'Left', `Risk Score`: 'GIRAFFE'}),
( b2:Person {name: 'b2', id:'10', Gender:'Male', Diagnosis: 'Normal', `Is Alive?`: 'No', Handedness: 'Left', `Risk Score`: 'PURPLE'})
CREATE
(a2)-[:SPOUSE]->(aSP2),
(b2)-[:CHILD]->(a2),
(b2)-[:CHILD]->(aSP2)
// Create the definition node for the first family:
CREATE
(famA:Family {family_ID:'A'})
WITH famA
MATCH (a:Person {name:"a"})-[*]-(b:Person)
MERGE (famA:Family)<-[:FAMILY]-(a)
MERGE (famA:Family)<-[:FAMILY]-(b)
// Create the definition node for the second family:
CREATE (famB:Family {family_ID:'B'})
WITH famB
MATCH (a2:Person {name:"a2"})-[*]-(b2:Person)
MERGE (famB:Family)<-[:FAMILY]-(a2)
MERGE (famB:Family)<-[:FAMILY]-(b2)
// Find the families with 2 or more Alzheimers cases
MATCH (fam:Family)<-[:FAMILY]-(person:Person)
WHERE person.Diagnosis = "Alzheimers"
WITH fam, count(person) AS fAlzCount
WHERE fAlzCount > 2
with fam
// Count the # of left-handed family members
MATCH (fam)-[:FAMILY]-(person:Person)
WHERE person.Handedness = 'Left'
WITH fam, count(person) AS LeftCount
// Count the total # of family members
MATCH (fam)-[:FAMILY]-(person:Person)
WITH fam, LeftCount, count(person) AS AllCount
// and then filter for families where more than 1/2 are left-handed
// tofloat() is used to convert the integer results so we can test
// against a float at the end
WHERE tofloat(LeftCount) / tofloat(AllCount) > 0.5
RETURN fam, LeftCount, AllCount
MATCH (Family:Family)<-[r:FAMILY]-(Person:Person)
WITH
Family, collect(Person) as F
WITH
Family, size(F) as sF, F,
filter(x in F where x.Handedness='Left') as LH,
filter(x in F where x.Diagnosis="Alzheimers" AND x.`Is Alive?`='No') as AD
WHERE
(size(LH) >= sF/2) AND (size(AD) >= 3)
RETURN Family,
F as wholeFamily,
extract(n IN AD | n.name) as whoAD,
size(LH) as sLH, size(AD) as sAD