2014-01-19 108 views
1

我有一個圖形,其中「User」類型的節點可以使用「SIMILAR」關係連接(或不連接)到其他「用戶」節點。在neo4j數據庫中找到不同的路徑

我想查找所有按其節點數排序的子圖(互連的「用戶」節點)。

例子: 想象我有這些節點(關係始終類型的 「相似」)

​​3210

我想獲得:

[A,B,C,D]; 
[E,F]; 
[Z]; 

使用Cypher支架或遍歷。

回答

3

在密碼中它會很昂貴。

事情是這樣的查詢:

MATCH m WITH collect(m) as all 
MATCH n 
RETURN distinct [x in all WHERE (n)-[*0..]-(x) | x.name] as cluster 

這將工作太,但可能同樣昂貴的:)

MATCH n-[*0..]-m 
WITH n, m 
ORDER BY id(m) 
WITH n, collect(m.name) as cluster 
RETURN distinct cluster 

在Java中它可能是這個樣子:

@Test 
public void testSimpleCluster() throws Exception { 
    createData(); 
    try (Transaction tx = db.beginTx()) { 
     TraversalDescription traversal = db.traversalDescription().depthFirst().uniqueness(Uniqueness.NODE_GLOBAL); 
     Map<Node, Set<Node>> clusters = new HashMap<>(); 
     GlobalGraphOperations ops = GlobalGraphOperations.at(db); 
     for (Node node : ops.getAllNodes()) { 
      if (inCluster(node, clusters) != null) continue; 
      clusters.put(node, IteratorUtil.addToCollection(traversal.traverse(node).nodes(), new HashSet<Node>())); 
     } 
     System.out.println("clusters = " + clusters.values()); 
     tx.success(); 
    } 
} 

private Node inCluster(Node node, Map<Node, Set<Node>> clusters) { 
    for (Map.Entry<Node, Set<Node>> entry : clusters.entrySet()) { 
     if (entry.getValue().contains(node)) return entry.getKey(); 
    } 
    return null; 
} 

private void createData() { 
    try (Transaction tx = db.beginTx()) { 
     Node a = node("a"); 
     Node b = node("b"); 
     Node c = node("c"); 
     Node d = node("d"); 
     Node e = node("e"); 
     Node f = node("f"); 
     Node z = node("z"); 
     connect(a, b); 
     connect(a, c); 
     connect(d, b); 
     connect(e, f); 
     tx.success(); 
    } 
} 

private void connect(Node a, Node b) { 
    a.createRelationshipTo(b, SIMILAR); 
} 

private Node node(String name) { 
    Node node = db.createNode(); 
    node.setProperty("name", name); 
    return node; 
} 
+0

感謝邁克爾的回答。 我正在嘗試java解決方案,但我找不到如何使用neo4jTemplate獲取所有節點。 – Monta

+0

我試圖用這種方式將密碼第二種解決方案適用於我的情況: START s = node:nodes(「com.xxx.domain.User」) MATCH s - [:SIMILAR * 0 ..] - s2 WITH s,s2 ORDER BY id(s2) WITH s,collect(s2)as cluster RETURN distinct distinct cluster 我在ORDER BY中得到一個錯誤 – Monta