5

我有一个存储在 Neo4j 中的大型网络。基于特定的根节点,我想在该节点周围提取一个子图并将其存储在其他地方。所以,我需要的是符合我的过滤条件的节点和边集。

Afaik 没有可用的开箱即用解决方案。有一个可用的图形匹配组件,但它仅适用于完美匹配。Neo4j API 本身只定义了图遍历,我可以使用它来定义应该访问哪些节点/边:

Traverser exp = Traversal
    .description()
    .breadthFirst()
    .evaluator(Evaluators.toDepth(2))
    .traverse(root);

现在,我可以将所有节点/边添加到所有路径的集合中,但这非常低效。你会怎么做?谢谢!

编辑将每个遍历的最后一个节点和最后一个关系添加到子图中是否有意义?

4

3 回答 3

3

至于图形匹配,它已被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为例

于 2013-04-19T13:07:21.230 回答
2

我通过构建基于所有遍历端点的诱导子图来解决它。

从每个遍历的最后一个节点和边的集合构建子图不起作用,因为不包括不属于任何最短路径的边。

代码片段如下所示:

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,我可以确保它只在集合中出现一次。

可以只迭代传入/传出边,但不清楚如何处理循环(从节点到自身的边)。它们属于哪个类别?这个片段没有这个问题。

于 2013-04-22T07:04:26.737 回答
0

请参阅将数据库转储到密码语句

dump START n=node({self}) MATCH p=(n)-[r:KNOWS*]->(m) RETURN n,r,m;

还有一个将第一个数据库 (db1) 的子图导入到第二个 (db2) 的示例。

于 2014-04-06T20:04:47.177 回答