我有一个存储在Neo4j中的大型网络。基于一个特定的根节点,我想在该节点周围提取一个子图,并将其存储在其他地方。所以,我需要的是符合我的过滤条件的节点和边的集合。
恐怕没有现成的解决方案。有一个图形匹配组件可用,但它只适用于完美匹配。Neo4j API本身只定义了图遍历,我可以用它来定义应该访问哪些节点/边缘:
Traverser exp = Traversal
.description()
.breadthFirst()
.evaluator(Evaluators.toDepth(2))
.traverse(root);
现在,我可以将所有节点/边添加到所有路径的集合中,但这是非常低效的。你会怎么做?谢谢!
EDIT将最后一个节点和每次遍历的最后一个关系添加到子图中是否有意义?
对于图匹配,已经被http://docs.neo4j.org/chunked/snapshot/cypher-query-lang.html取代了,它可以很好地匹配,并且支持带有可选关系的模糊匹配。
对于子图表示,我将使用Cypher输出来构建新的Cypher语句来重新创建图,类似于SQL导出,类似于
start n=node:node_auto_index(name='Neo')
match n-[r:KNOWS*]-m
return "create ({name:'"+m.name+"'});"
http://console.neo4j.org/r/pqf1rp,例如
我通过构造基于所有遍历端点的诱导子图来解决它。
从每次遍历的最后一个节点和边的集合中构建子图是无效的,因为不属于最短路径的边将不包括在内。
代码片段如下所示:
Set<Node> nodes = new HashSet<Node>();
Set<Relationship> edges = new HashSet<Relationship>();
for (Node n : traverser.nodes())
{
nodes.add(n);
}
for (Node node : nodes)
{
for (Relationship rel : node.getRelationships())
{
if (nodes.contains(rel.getOtherNode(node)))
edges.add(rel);
}
}
每条边添加两次。一次用于传出节点,一次用于传入节点。使用Set,我可以确保它只在集合中出现一次。
可以只迭代传入/传出边,但不清楚如何处理循环(从节点到自身的边)。他们属于哪一类?这个代码片段没有这个问题。
参见转储数据库到密码语句
dump START n=node({self}) MATCH p=(n)-[r:KNOWS*]->(m) RETURN n,r,m;
还有一个将第一个数据库(db1)的子图导入到第二个数据库(db2)的示例。