以程序方式开发密码查询
Develop a cypher query in a procedural manner
我一直在研究家谱图。
我想回答一个简单的问题:
Return
任何家庭
- 有 3 个或更多阿尔茨海默氏症患者
- 已故
- 并且来自一个以左撇子为主的家庭(至少 50%)。
我模拟了两个家庭,一个满足条件,一个不满足条件(问题末尾的代码)。
较大的家庭满足标准。较小的家庭没有。 (旁注:我将定义节点放在每个家庭上,以便于区分它们,并且在进行匹配时 return 只有一个家庭)。
我想我已经找到了解决方案的某些部分,但我不知道如何以一种有凝聚力的方式将它们粘合在一起。
例如(感谢@Tim Kuehn and ),我可以找到 return 满足条件的树,即有 3 个阿尔茨海默氏症患者:
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 (n { family_ID: 'A' })--(x)
RETURN count(x) as Tot
我还能算出有多少人是左撇子:
MATCH (f:Family)<-[:FAMILY]-(person:Person)
WHERE person.Handedness = 'Left'
WITH f, count(person) AS Count
RETURN Count
但到目前为止,我尝试以某种程序方式开发此查询的尝试没有奏效。
我尝试了这些方法:
MATCH (f:Family)<-[:FAMILY]-(person:Person)
WHERE person.Diagnosis = "Alzheimers"
AND person.Handedness = "Left"
WITH f, count(person) AS Count
WHERE Count > 2
MATCH (a:Person)-[r1:FAMILY]-(f)
WITH a,
MATCH (n { family_ID: 'A' })--(x)
RETURN count(x) as Tot
但这基本上是胡言乱语。我得到一个语法错误,最重要的是。
在其他查询语言中,通常建议逐步进行,也许通过一系列临时表的管道结果直到数据处于正确的形式。我似乎无法弄清楚如何在 CQL 中做类似的事情。也许我不知道如何将结果传送到集合中?我不知道该去哪里。
我创建数据库的代码:
// 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
我认为 filters - 这就是您所需要的:
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
我一直在研究家谱图。
我想回答一个简单的问题:
Return
任何家庭- 有 3 个或更多阿尔茨海默氏症患者
- 已故
- 并且来自一个以左撇子为主的家庭(至少 50%)。
我模拟了两个家庭,一个满足条件,一个不满足条件(问题末尾的代码)。
较大的家庭满足标准。较小的家庭没有。 (旁注:我将定义节点放在每个家庭上,以便于区分它们,并且在进行匹配时 return 只有一个家庭)。
我想我已经找到了解决方案的某些部分,但我不知道如何以一种有凝聚力的方式将它们粘合在一起。
例如(感谢@Tim Kuehn
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 (n { family_ID: 'A' })--(x)
RETURN count(x) as Tot
我还能算出有多少人是左撇子:
MATCH (f:Family)<-[:FAMILY]-(person:Person)
WHERE person.Handedness = 'Left'
WITH f, count(person) AS Count
RETURN Count
但到目前为止,我尝试以某种程序方式开发此查询的尝试没有奏效。
我尝试了这些方法:
MATCH (f:Family)<-[:FAMILY]-(person:Person)
WHERE person.Diagnosis = "Alzheimers"
AND person.Handedness = "Left"
WITH f, count(person) AS Count
WHERE Count > 2
MATCH (a:Person)-[r1:FAMILY]-(f)
WITH a,
MATCH (n { family_ID: 'A' })--(x)
RETURN count(x) as Tot
但这基本上是胡言乱语。我得到一个语法错误,最重要的是。
在其他查询语言中,通常建议逐步进行,也许通过一系列临时表的管道结果直到数据处于正确的形式。我似乎无法弄清楚如何在 CQL 中做类似的事情。也许我不知道如何将结果传送到集合中?我不知道该去哪里。
我创建数据库的代码:
// 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
我认为 filters - 这就是您所需要的:
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