Graph neo4j多重匹配聚合-单传递图?

Graph neo4j多重匹配聚合-单传递图?,graph,neo4j,cypher,Graph,Neo4j,Cypher,我有一张像这样的图 在neo4j中 CREATE (Alice:Person {id:'a', fraud:1}) CREATE (Bob:Person {id:'b', fraud:0}) CREATE (Charlie:Person {id:'c', fraud:0}) CREATE (David:Person {id:'d', fraud:0}) CREATE (Esther:Person {id:'e', fraud:0}) CREATE (Fanny:Person {id:'f',

我有一张像这样的图

在neo4j中

CREATE (Alice:Person {id:'a', fraud:1})
CREATE (Bob:Person {id:'b', fraud:0})
CREATE (Charlie:Person {id:'c', fraud:0})
CREATE (David:Person {id:'d', fraud:0})
CREATE (Esther:Person {id:'e', fraud:0})
CREATE (Fanny:Person {id:'f', fraud:0})
CREATE (Gabby:Person {id:'g', fraud:0})
CREATE (Fraudster:Person {id:'h', fraud:1})


CREATE
  (Alice)-[:CALL]->(Bob),
  (Bob)-[:SMS]->(Charlie),
  (Charlie)-[:SMS]->(Bob),
  (Fanny)-[:SMS]->(Charlie),
  (Esther)-[:SMS]->(Fanny),
  (Esther)-[:CALL]->(David),
  (David)-[:CALL]->(Alice),
  (David)-[:SMS]->(Esther),
  (Alice)-[:CALL]->(Esther),
  (Alice)-[:CALL]->(Fanny),
  (Fanny)-[:CALL]->(Fraudster)
允许轻松计算社交网络的欺诈百分比:

MATCH (:Person)-[:CALL|:SMS]->(f:Person)
WITH TOFLOAT(COUNT(*))/100 AS divisor, COLLECT(f) AS fs
UNWIND fs AS f
WITH divisor, f
WHERE f.fraud = 1
RETURN f, COUNT(*)/divisor AS percentage
如何修改此选项以对不同类型的关系使用多个匹配项,但仍然只需要对图形进行一次遍历?也就是说,有比简单地调用以下3个语句更有效的方法:

MATCH (:Person)-[:CALL]->(f:Person)
    WITH TOFLOAT(COUNT(*))/100 AS divisor, COLLECT(f) AS fs
    UNWIND fs AS f
    WITH divisor, f
    WHERE f.fraud = 1
    RETURN f, COUNT(*)/divisor AS percentage

MATCH (:Person)-[:SMS]->(f:Person)
    WITH TOFLOAT(COUNT(*))/100 AS divisor, COLLECT(f) AS fs
    UNWIND fs AS f
    WITH divisor, f
    WHERE f.fraud = 1
    RETURN f, COUNT(*)/divisor AS percentage

MATCH (:Person)-[:CALL|:SMS]->(f:Person)
    WITH TOFLOAT(COUNT(*))/100 AS divisor, COLLECT(f) AS fs
    UNWIND fs AS f
    WITH divisor, f
    WHERE f.fraud = 1
    RETURN f, COUNT(*)/divisor AS percentage

但是,如果您想将结果保存在一起,您需要使用
链接查询,并为此人传递
f
变量,而不是返回
percentage\u total、percentage\u sms、percentage\u phone

。不幸的是,您还必须使用
子句在所有
中传递所有
百分比*
变量,因此很难维护:

MATCH (f:Person)    
OPTIONAL MATCH (:Person)-[:CALL|:SMS]->(f)
    WITH TOFLOAT(COUNT(*))/100 AS divisor, COLLECT(f) AS fs
    UNWIND fs AS f
    WITH divisor, f
    WHERE f.fraud = 1
    WITH f, COUNT(*)/divisor AS percentage_all

OPTIONAL MATCH (:Person)-[:CALL]->(f)
    WITH TOFLOAT(COUNT(*))/100 AS divisor, COLLECT(f) AS fs, percentage_all
    UNWIND fs AS f
    WITH divisor, f, percentage_all
    WHERE f.fraud = 1
    WITH f, percentage_all, COUNT(*)/divisor AS percentage_phone

OPTIONAL MATCH (:Person)-[:SMS]->(f)
    WITH TOFLOAT(COUNT(*))/100 AS divisor, COLLECT(f) AS fs, percentage_all, percentage_phone
    UNWIND fs AS f
    WITH divisor, f, percentage_all, percentage_phone
    WHERE f.fraud = 1
    RETURN f, percentage_all, percentage_phone, COUNT(*)/divisor AS percentage_sms

openCypher项目已经提出,但这将需要一些时间才能实现Neo4j。

如果您希望将结果保存在一起,则需要使用
链接查询,并为人员传递
f
变量。不幸的是,您还必须使用
子句在所有
中传递所有
百分比*
变量,因此很难维护:

MATCH (f:Person)    
OPTIONAL MATCH (:Person)-[:CALL|:SMS]->(f)
    WITH TOFLOAT(COUNT(*))/100 AS divisor, COLLECT(f) AS fs
    UNWIND fs AS f
    WITH divisor, f
    WHERE f.fraud = 1
    WITH f, COUNT(*)/divisor AS percentage_all

OPTIONAL MATCH (:Person)-[:CALL]->(f)
    WITH TOFLOAT(COUNT(*))/100 AS divisor, COLLECT(f) AS fs, percentage_all
    UNWIND fs AS f
    WITH divisor, f, percentage_all
    WHERE f.fraud = 1
    WITH f, percentage_all, COUNT(*)/divisor AS percentage_phone

OPTIONAL MATCH (:Person)-[:SMS]->(f)
    WITH TOFLOAT(COUNT(*))/100 AS divisor, COLLECT(f) AS fs, percentage_all, percentage_phone
    UNWIND fs AS f
    WITH divisor, f, percentage_all, percentage_phone
    WHERE f.fraud = 1
    RETURN f, percentage_all, percentage_phone, COUNT(*)/divisor AS percentage_sms

提议的openCypher项目,但这需要一些时间才能实现Neo4j。

UNION
不是一个选项?但这只会连接结果,而不会为一个顶点提供3个不同的列?
UNION
不是一个选项?但这只会连接结果,而不会为一个顶点提供3个不同的列?尽管最后一个应该是第一个查询-和其他所有可选匹配,即当前返回一个空集。好的一点-我更新了查询,为所有三个查询添加了可选项。另外一个改进是简单地通过平均值进行聚合(假设欺诈为0或1,以更有效地计算百分比
avg(f.fraud)
-但我不确定如何将其集成到cypher中。虽然最后一个应该是第一个查询,其余的都是可选的匹配项,即当前返回一个空集。很好的一点是,我更新了查询,为所有三个查询都添加了可选项。还有一个改进是简单地通过平均值聚合(假设欺诈为0或1,以更有效地计算百分比
avg(f.fraud)
——但我不确定如何将其集成到cypher中。