2017-06-08 61 views
1

我通過GraphDatabaseService訪問neo4j數據庫。我添加了一些節點和關係,並希望進行查詢。我的目標是讓所有與呼叫終端有呼叫關係的節點。所以我有整個路徑到這個節點。 (例如:節點1 -calling->節點2 -calling * - >節點X -calling->終端節點)從Java執行對neo4j數據庫的查詢,解析結果

我想是這樣的:

GraphDatabaseService _graphDatabase; // db is running and working fine 
Node node;//given by the function call 

HashMap<String, Object> properties = Maps.newHashMap(); 
properties.put("name", getPropertyFromNode(node, "name")); 
String query = "MATCH p=(startnode)-[rel:CALLING*]->(endnode) WHERE endnode.name = {name} RETURN p"; 

Result result = _graphDatabase.execute(query, properties); 
while (result.hasNext()) { 
    Map<String, Object> next = result.next(); 
    next.forEach((k, v) -> { 
     System.out.println(k + " : " + v.toString()); 
     if (v instanceof PathImpl) { 
      PathImpl pathImpl = (PathImpl) v; 
      String startNodeName = getPropertyFromNode(pathImpl.startNode(), "name"); 
      String endNodeName = getPropertyFromNode(pathImpl.endNode(), "name"); 
      System.out.println(startNodeName + " -calling-> " + endNodeName); 
     } 
    }); 
} 

public String getPropertyFromNode(Node node, String propertyName) { 
    String result = null; 
    try (Transaction transaction = _graphDatabase.beginTx()) { 
     result =node.getProperty(propertyName).toString(); 
     transaction.success(); 
    } 
    return result; 
} 

問題對我來說,這個結果是一個地圖< '字符串,對象>,並且我想要得到id或關係中的節點的名稱。我試圖將對象轉換爲PathImpl,因爲那是返回的類型(通過調試計算出來),但它像接口那樣處於不同的類加載器中,因此語句instanceof返回false。 (24929) - [CALLING,108061] - >(24930))

我的問題是,我可以訪問這個以更好的方式獲得信息,或者如何改變classLoader(如果這是問題,我正在gradle項目中使用eclipse)來發生這樣的事情。 我不想解析字符串來獲取ID的,並通過該屬性從數據庫中獲取節點,它的接縫對我來說很醜。

回答

0

試圖cybersam的有效回答改變暗號查詢後,我發現另一種方式在不改變該查詢,適合我的目標更好。 對於我來說,目標是獲得整個路徑,不僅是鏈接節點的名稱/ ID。該信息正是我想要的參數'p'(請參閱查詢),但我不能投這種類型。 原因是Neo4j正在使用PathImpl的內部實現。 爲了讓我的解決方案在問題工作中,我必須使用Path而不是PathImpl,所以我不必導入實習生類型。所以我改變了進口:

import org.neo4j.graphalgo.impl.util.PathImpl; 

import org.neo4j.graphdb.Path; 

和測試路徑,而不是PathImpl。

if (v instanceof Path) { 
    Path path = (Path) v; 
    Iterable<Node> nodes = path.nodes(); 
    nodes.forEach(n -> System.out.println(n.toString())); 
} 

現在我可以訪問整個路徑。希望這也能幫助其他人。

1

如果您想獲取開始和結束節點的名稱,那麼您應該修改Cypher代碼以返回它們(而不是路徑),這將極大地簡化從響應中提取數據所需的代碼。例如:

MATCH p=(startnode)-[rel:CALLING*]->(endnode) 
WHERE endnode.name = {name} 
RETURN startnode.name AS s_name, endnode.name AS e_name, p; 
+0

看起來像我深入到用java解決這個問題,而不是思考兩次有關密碼查詢,thx – Stefan

+0

問題這種方式是即時通訊丟失關於節點之間的關係的信息...所以我得到了所有的列表節點是的,但我不知道路徑如何看起來像 – Stefan

+0

爲了獲得路徑,你只需要在'RETURN'子句中包含路徑'p'。我已經更新了我的答案。 – cybersam