我在Neo4j数据库中有一个大的有向图,并希望提取一个有代表性的样本子图,同时尊重图的结构。
每个节点都有U
,T
,H
,A
或E
标签。该图是一个树林,每棵树的根都是U
个节点。叶节点可以是T
,H
,A
或E
个节点。中间节点仅为T
个节点。对于提取物,
A
和E
(叶子)节点。请注意,基于节点的简单采样的提取将具有与整个图形不同的结构。
答案 0 :(得分:1)
我发现Sampling a Neo4j database帮助我编写了cypher查询的第一部分:
MATCH (selectedU:U) WHERE rand() < 0.1 RETURN selectedU;
根据需要返回大约10%的U
个节点。
以下查询返回我需要的节点和关系(来自整个图表,因为还没有应用采样!):
MATCH p=(u:U)-->(n1)-[*]->(n2)
WHERE n1:T AND (n2:T OR n2:H)
WITH nodes(p) AS nodePairsInPath
UNWIND nodePairsInPath AS nodes
RETURN DISTINCT nodes AS g
UNION ALL
MATCH p=(u:U)-->(n1)-[*]->(n2)
WHERE n1:T AND (n2:T OR n2:H)
WITH relationships(p) AS relPairsInPath
UNWIND relPairsInPath AS rels
RETURN DISTINCT rels AS g;
我合并了两个cypher查询,因此只返回以所选U
个节点开头的路径中的节点和关系:
MATCH (selectedU:U) WHERE rand() < 0.1
WITH selectedU
MATCH p=(selectedU)-->(n1)-[*]->(n2)
WHERE n1:T AND (n2:T OR n2:H)
WITH nodes(p) AS nodePairsInPath
UNWIND nodePairsInPath AS nodes
RETURN DISTINCT nodes AS g
UNION ALL
MATCH p=(selectedU)-->(n1)-[*]->(n2)
WHERE n1:T AND (n2:T OR n2:H)
WITH relationships(p) AS relPairsInPath
UNWIND relPairsInPath AS rels
RETURN DISTINCT rels AS g;
还有一个小问题,如果采样大小太小(因此找不到selectedU
),合并后的查询将返回U
,T
之间的关系和H
个节点。查询在这种边缘情况下不返回任何记录(节点或关系)会更好。
我认为这可能是一个常见的用例,需要随机子图,但子图需要遵循整体图的结构。 作为新手密码用户,这对我来说非常具有挑战性,所以我在这里发帖,希望它可能会对有类似要求的其他人有所帮助。
写这个密码查询教会了我很多关于语言的知识,虽然我希望密码专家可以做得更好......
答案 1 :(得分:1)
path expansion的APOC程序应该非常有用。
例如,要获得10%的子图(作为节点):
MATCH (root:U)
WHERE rand() < .1
CALL apoc.path.subgraphNodes(root, {labelFilter:'-A|E'}) YIELD node
RETURN root, COLLECT(node) AS subgraph_nodes;
labelFilter
值指定A
和E
个节点应列入黑名单。您说您不想将它们作为叶节点返回,并且您的描述暗示它们仅用作叶节点。