Graph Neo4j:遍历子对象并基于属性在子对象之间创建有序关系
我在neo4j中有一个图形,看起来像。我想把它做成这样 广义问题: 如何按特定顺序(例如,按日期顺序)遍历子项,并在给定顺序的子项之间创建关系 具体问题: 每个(:Person)可以有多个(:Diagnosis)节点,多个(:Diagnosis)节点可以共享相同的(:Concept)。标记为“条件”的节点是(:概念)节点。(:Diagnosis)节点表示一个人诊断的发生,因此没有两个人共享(:Diagnosis)节点。但是,可以用同一种诊断对多人进行诊断,诊断类型(如II型糖尿病、动脉瘤等)由(:概念)节点描述 我想根据(:Diagnosis)节点的时间顺序创建(:Concept)节点之间的关系路径,并且我只想包括每个(:Concept)节点第一次被诊断的时间 到目前为止,我在(:个人)和(:概念)之间建立了如下新关系:Graph Neo4j:遍历子对象并基于属性在子对象之间创建有序关系,graph,neo4j,nodes,relationship,with-statement,Graph,Neo4j,Nodes,Relationship,With Statement,我在neo4j中有一个图形,看起来像。我想把它做成这样 广义问题: 如何按特定顺序(例如,按日期顺序)遍历子项,并在给定顺序的子项之间创建关系 具体问题: 每个(:Person)可以有多个(:Diagnosis)节点,多个(:Diagnosis)节点可以共享相同的(:Concept)。标记为“条件”的节点是(:概念)节点。(:Diagnosis)节点表示一个人诊断的发生,因此没有两个人共享(:Diagnosis)节点。但是,可以用同一种诊断对多人进行诊断,诊断类型(如II型糖尿病、动脉瘤等)由(
(:Person {person_id: <some_number>})-[:DIAGNOSED_WITH {start_date: yyyy/mm/dd}]->(:Concept)
(concept 1)-[:NEXT {person_id: #}]->(concept 2)-[:NEXT {person_id: #})]->(concept 3)...
现在,我想根据[:Diagnostics_WITH]关系中的开始日期在(:Concept)节点之间创建关系。它应该是这样的:
(:Person {person_id: <some_number>})-[:DIAGNOSED_WITH {start_date: yyyy/mm/dd}]->(:Concept)
(concept 1)-[:NEXT {person_id: #}]->(concept 2)-[:NEXT {person_id: #})]->(concept 3)...
我试着对一个给定(:个人)的所有关系集合使用UNWIND
,但我不太明白UNWIND
如何与一起工作
以下查询似乎只是绘制在同一开始日期进行诊断的所有(:Concept)节点之间的关系:
match (p:Person {person_id: "12345"})-[d:DIAGNOSED_WITH]->(c:Concept) WITH
p.person_id AS person_id, d AS diagnoses ORDER BY d.start_date
WITH collect(diagnoses) as ordered_diagnoses, person_id as person_id
UNWIND ordered_diagnoses as diagnosis
MATCH (:Person {person_id: person_id})-[diagnosis]->(c1:Concept)
MATCH (:Person {person_id: person_id})-[d2:DIAGNOSED_WITH]->(c2:Concept) WHERE
d2.start_date >= diagnosis.start_date AND d2 <> diagnosis
WITH min(d2.start_date) AS min_start_date2, diagnosis, person_id, c1
MATCH (:Person {person_id: person_id})-[:DIAGNOSED_WITH {start_date:
min_start_date2}]->(c2:Concept)
MERGE (c1)-[:NEXT {person_id: person_id, start_date1: diagnosis.start_date,
start_date2: min_start_date2}]->(c2)
请帮忙!谢谢 我决定停止用cypher进行黑客攻击,只使用py2neo包在python中进行攻击。要简单得多。以下是您感兴趣的代码:
#!/usr/bin/env python
from py2neo import authenticate, Graph
from py2neo import Node, Relationship
authenticate("localhost:7474", "neo4j", "neo3j")
# default uri for local Neo4j instance
graphdb = Graph('http://localhost:7474/db/data')
def set_NEXT_rels(person_id):
concepts = graphdb.run("MATCH (p:Person {person_id: \""+person_id+"\"})-[d:DIAGNOSED_WITH]->(c:Concept) RETURN c.concept_id, d.start_date ORDER BY d.start_date, c.concept_name").data()
for i in range(0, len(concepts)-1):
d = graphdb.run("MATCH (p:Person {person_id: \""+person_id+"\"})-[d1:DIAGNOSED_WITH {start_date: \""+concepts[i]['d.start_date']+"\"}]->(c1:Concept {concept_id: \""+concepts[i]['c.concept_id']+"\"}) MATCH (p:Person {person_id: \""+person_id+"\"})-[d2:DIAGNOSED_WITH {start_date: \""+concepts[i+1]['d.start_date']+"\"}]->(c2:Concept {concept_id: \""+concepts[i+1]['c.concept_id']+"\"}) MERGE (c1)-[:NEXT {person_id: \""+person_id+"\", start_date_d1: d1.start_date, start_date_d2: d2.start_date}]->(c2)").data()
def process_conditions_by_person():
people = graphdb.run("MATCH (p:Person) RETURN p.person_id").data()
for person in people:
set_NEXT_rels(person['p.person_id'])
def main():
process_conditions_by_person()
if __name__ == "__main__":
main()
这家公司有办法帮你。具体来说,在helpers部分的Collection Functions小节中,有一个过程apoc.coll.pairs([list])
,它将接收列表并输出子列表对的列表。最后一对将是列表中与null成对的最后一个元素,因此如果我们的目标是连接节点,则应该删除该元素
下面是一个用法示例:
WITH [1, 2, 3, 4, 5] AS stuff
CALL apoc.coll.pairs(stuff) YIELD value
WITH value[0..size(value)-1] AS numbers
RETURN numbers
这将输出:[[1,2],[2,3],[3,4],[4,5]]
因此,在使用它连接节点时,您可以通过查询搜索感兴趣的节点,根据需要对它们进行排序,将它们收集到一个列表中,调用pairs()APOC过程,然后使用FOREACH创建每对节点之间的关系
编辑
自我回答后,APOC的一些变化:
1) apoc.coll.pairs()
现在是一个函数,而不是一个过程(无需使用CALL或YIELD,您可以内联使用它)
2) apoc.nodes.link()
是一个获取节点集合并在它们之间创建给定类型关系的过程(因此您不必在foreach中自己创建关系),通常是链接节点的首选方式