添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
  • Cypher实现
  • // 分层封装数据【获取指定结构的树】,返回结果中每一层每个节点包含该节点关联的关系ID、节点ID;如果需要在返回结果中包含节点、关系属性和类型信息,可以在对应Cypher查询位置处进行封装一并返回。
    // 匹配需要处理的路径
    MATCH p=(c:Class {name:'电影'})-[r1:实例]->(m:Movie)<-[r2:ACTED_IN]-(:Person) 
    	// 收集两层关系
        WITH COLLECT(DISTINCT r1) AS hc_r1,COLLECT(DISTINCT r2) AS hc_r2
        // 解析第一层NODE,第二层NODE,第三层NODE
        // NODE对象结构:node-当前层节点,f_node表示父级节点,rel表示当前节点的关系
        WITH REDUCE(l=[],r IN hc_r1 | l+apoc.map.setPairs({},[["node",ID(STARTNODE(r))],["rel",ID(r)]])) AS hc_n1,
        	REDUCE(l=[],r IN hc_r1 | l+apoc.map.setPairs({},[["f_node",ID(STARTNODE(r))],["node",ID(ENDNODE(r))],["rel",ID(r)]])) AS hc_n2,
            REDUCE(l=[],r IN hc_r2 | l+apoc.map.setPairs({},[["f_node",ID(ENDNODE(r))],["node",ID(STARTNODE(r))],["rel",ID(r)]])) AS hc_n3
        // 通过上一次处理后,每一层节点、关联关系以及父级节点都准备好了,下一步需要将`node`排重,然后将`f_node`和`rel`收集在一个数组
        // 当前节点的父级节点和关联关系可能有多个,所以排重后需要增加两个map字段`f_nodes`和`rels`
        WITH hc_n1,hc_n2,hc_n3
        WITH apoc.map.groupByMulti(hc_n1,'node') AS hc_n1_gp,EXTRACT(map IN hc_n1 | map.node) AS hc_n_l1, 
        	apoc.map.groupByMulti(hc_n2,'node') AS hc_n2_gp,EXTRACT(map IN hc_n2 | map.node) AS hc_n_l2, 
            apoc.map.groupByMulti(hc_n3,'node') AS hc_n3_gp,EXTRACT(map IN hc_n3 | map.node) AS hc_n_l3
        // 封装最终返回的每一层数据格式[{cur_node:node,f_nodes:[2,123],rels:[213,23]}]
        WITH REDUCE(l=[],nd IN hc_n_l1 | l+apoc.map.setPairs({},[["cur_node",nd],["f_nodes",apoc.coll.toSet(FILTER(e IN EXTRACT(mp IN apoc.map.get(hc_n1_gp,TOSTRING(nd),NULL,FALSE) | mp.f_node) WHERE e IS NOT NULL))],["rels",apoc.coll.toSet(FILTER(e IN EXTRACT(mp IN apoc.map.get(hc_n1_gp,TOSTRING(nd),NULL,FALSE) | mp.rel) WHERE e IS NOT NULL))]])) AS hc1,
        	REDUCE(l=[],nd IN hc_n_l2 | l+apoc.map.setPairs({},[["cur_node",nd],["f_nodes",apoc.coll.toSet(FILTER(e IN EXTRACT(mp IN apoc.map.get(hc_n2_gp,TOSTRING(nd),NULL,FALSE) | mp.f_node) WHERE e IS NOT NULL))],["rels",apoc.coll.toSet(FILTER(e IN EXTRACT(mp IN apoc.map.get(hc_n2_gp,TOSTRING(nd),NULL,FALSE) | mp.rel) WHERE e IS NOT NULL))]])) AS hc2,
            REDUCE(l=[],nd IN hc_n_l3 | l+apoc.map.setPairs({},[["cur_node",nd],["f_nodes",apoc.coll.toSet(FILTER(e IN EXTRACT(mp IN apoc.map.get(hc_n3_gp,TOSTRING(nd),NULL,FALSE) | mp.f_node) WHERE e IS NOT NULL))],["rels",apoc.coll.toSet(FILTER(e IN EXTRACT(mp IN apoc.map.get(hc_n3_gp,TOSTRING(nd),NULL,FALSE) | mp.rel) WHERE e IS NOT NULL))]])) AS hc3
    // 使用apoc.coll.toSet排重列表
    RETURN apoc.coll.toSet(hc1) AS hc1,
    		apoc.coll.toSet(hc2) AS hc2,
    		apoc.coll.toSet(hc3) AS hc3
    

    参考链接:使用Cypher获取指定结构的树