neo4j单次传递图,但多次匹配

时间:2017-12-03 10:58:33

标签: graph neo4j cypher

我在neo4j中有一个顶点为:

的图形
gci C:\temp\list*.txt -file | %{gc $_.FullName |  select -Skip 1} | sort -Unique > c:\temp\newfile.txt

和边缘:

person:ID,name,value:int,:LABEL
1,Alice,1,Person
2,Bob,0,Person
3,Charlie,0,Person
4,David,0,Person
5,Esther,0,Person
6,Fanny,0,Person
7,Gabby,0,Person
8,XXXX,1,Person

导入neo4j,如:

:START_ID,:END_ID,:TYPE
1,2,call
2,3,text
3,2,text
6,3,text
5,6,text
5,4,call
4,1,call
4,5,text
1,5,call
1,8,call
6,8,call
6,8,text
8,6,text
7,1,text

看起来像: enter image description here

现在查询图表时如下:

DATA_DIR_SAMPLE=/data_network/
$NEO4J_HOME/bin/neo4j-admin import --mode=csv \
  --database=graph.db \
  --nodes:Person ${DATA_DIR_SAMPLE}/vertices.csv \
  --relationships ${DATA_DIR_SAMPLE}/edges.csv

可以看到图表被遍历了多次,另外我想获得一个像这样的表:

MATCH (source:Person)-[*1]-(destination:Person)
RETURN source.name, source.value, avg(destination.value), 'undir_1_any' as type
UNION ALL
MATCH (source:Person)-[*2]-(destination:Person)
RETURN source.name, source.value, avg(destination.value), 'undir_2_any' as type

需要额外的聚合步骤(pivot / reshape)

enter image description here

将来,我想添加以下模式

  • 无向|定向
  • 所有关系|关系类型
  • 最多可在图表中列出3个级别 以及这些
  • 的所有排列

是否有更好的方法来合并查询?

1 个答案:

答案 0 :(得分:1)

您需要沿路径长度聚合,同时使用自定义函数计算平均值:

MATCH p = (source:Person)-[*1..2]-(destination:Person)
WITH 
  length(p) as L, source, destination
RETURN 
  source.name as Vertex, 
  source.value as value, 
  1.0 * 
      sum(CASE WHEN L = 1 THEN destination.value ELSE 0 END) / 
      sum(CASE WHEN L = 1 THEN 1 ELSE 0 END) as type_undir_1_any,
  1.0 * 
      sum(CASE WHEN L = 2 THEN destination.value ELSE 0 END) /
      sum(CASE WHEN L = 2 THEN 1 ELSE 0 END) as type_undir_2_any

或者是一个更优雅的版本,其中包含来自APOC library的函数来计算集合的平均值:

MATCH p = (source:Person)-[*1..2]-(destination:Person)
RETURN 
  source.name as Vertex, 
  source.value as value,
  apoc.coll.avg(COLLECT(
    CASE WHEN length(p) = 1 THEN destination.value ELSE NULL END
  )) as type_undir_1_any,
  apoc.coll.avg(COLLECT(
    CASE WHEN length(p) = 2 THEN destination.value ELSE NULL END
  )) as type_undir_2_any