Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Graph Neo4j:遍历子对象并基于属性在子对象之间创建有序关系_Graph_Neo4j_Nodes_Relationship_With Statement - Fatal编程技术网

Graph Neo4j:遍历子对象并基于属性在子对象之间创建有序关系

Graph Neo4j:遍历子对象并基于属性在子对象之间创建有序关系,graph,neo4j,nodes,relationship,with-statement,Graph,Neo4j,Nodes,Relationship,With Statement,我在neo4j中有一个图形,看起来像。我想把它做成这样 广义问题: 如何按特定顺序(例如,按日期顺序)遍历子项,并在给定顺序的子项之间创建关系 具体问题: 每个(:Person)可以有多个(:Diagnosis)节点,多个(:Diagnosis)节点可以共享相同的(:Concept)。标记为“条件”的节点是(:概念)节点。(:Diagnosis)节点表示一个人诊断的发生,因此没有两个人共享(:Diagnosis)节点。但是,可以用同一种诊断对多人进行诊断,诊断类型(如II型糖尿病、动脉瘤等)由(

我在neo4j中有一个图形,看起来像。我想把它做成这样

广义问题:

如何按特定顺序(例如,按日期顺序)遍历子项,并在给定顺序的子项之间创建关系

具体问题:

每个(:Person)可以有多个(:Diagnosis)节点,多个(:Diagnosis)节点可以共享相同的(:Concept)。标记为“条件”的节点是(:概念)节点。(:Diagnosis)节点表示一个人诊断的发生,因此没有两个人共享(:Diagnosis)节点。但是,可以用同一种诊断对多人进行诊断,诊断类型(如II型糖尿病、动脉瘤等)由(:概念)节点描述

我想根据(:Diagnosis)节点的时间顺序创建(:Concept)节点之间的关系路径,并且我只想包括每个(: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)...
现在,我想根据[: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中自己创建关系),通常是链接节点的首选方式