2014-12-01 228 views
2

如果這是重複的,則排除,儘管目前爲止我沒有找到答案。java neo4j檢查是否存在關係

我有一個應用程序通過cypher語句針對REST-API創建節點和關係。我創建關係與下面的代碼:

public URI createRelationship(GraphNodeTypes sourceType, URI sourceNode, 
         GraphNodeTypes targetType, URI targetNode, 
    GraphRelationshipTypes relationshipType, String[] jsonAttributes) { 
URI relationShipLocation = null; 

String cypherArt = getNodeIdFromLocation(sourceNode)+"-[:"+relationshipType+"]->"+getNodeIdFromLocation(targetNode); 

logger.info("creating relationship ({}:{}) -[:{}]-> ({}:{})", 
           sourceType, 
           getNodeIdFromLocation(sourceNode), 
           relationshipType, 
           targetType, 
           getNodeIdFromLocation(targetNode)); 

try { 
    URI finalUrl = new URI(sourceNode.toString() + "/relationships"); 
    String cypherStatement = generateJsonRelationship(targetNode, 
                 relationshipType, 
                 jsonAttributes); 

    logger.trace("sending CREATE RELATIONSHIP cypher as {} to endpoint {}", cypherStatement, finalUrl); 
    WebResource resource = Client.create().resource(finalUrl); 

    ClientResponse response = resource 
      .accept(MediaType.APPLICATION_JSON) 
      .type(MediaType.APPLICATION_JSON) 
      .entity(cypherStatement) 
      .post(ClientResponse.class); 

    String responseEntity = response.getEntity(String.class).toString(); 
    int responseStatus = response.getStatus(); 

    logger.trace("POST to {} returned status code {}, returned data: {}", 
      finalUrl, responseStatus, 
      responseEntity); 

    // first check if the http code was ok 
    HttpStatusCodes httpStatusCodes = HttpStatusCodes.getHttpStatusCode(responseStatus); 
    if (!httpStatusCodes.isOk()){ 
     if (httpStatusCodes == HttpStatusCodes.FORBIDDEN){ 
      logger.error(HttpErrorMessages.getHttpErrorText(httpStatusCodes.getErrorCode())); 
     } else { 
      logger.error("Error {} sending data to {}: {} ", response.getStatus(), finalUrl, HttpErrorMessages.getHttpErrorText(httpStatusCodes.getErrorCode())); 
     } 
    } else { 
     JSONParser reponseParser = new JSONParser(); 
     Object responseObj = reponseParser.parse(responseEntity); 
     JSONObject jsonResponseObj = responseObj instanceof JSONObject ?(JSONObject) responseObj : null; 
     if(jsonResponseObj == null) 
      throw new ParseException(0, "returned json object is null"); 

     //logger.trace("returned response object is {}", jsonResponseObj.toString()); 
     try { 
      relationShipLocation = new URI((String)((JSONObject)((JSONArray)((JSONObject)((JSONArray)((JSONObject)((JSONArray)jsonResponseObj.get("results")).get(0)).get("data")).get(0)).get("rest")).get(0)).get("self")); 
     } catch (Exception e) { 
      logger.warn("CREATE RELATIONSHIP statement did not return a self object, returning null -- error was {}", e.getMessage()); 
      relationShipLocation = null; 
     } 
    } 
} catch (Exception e) { 
    logger.error("could not create relationship "); 
} 
return relationShipLocation; 
} 

private static String generateJsonRelationship(URI endNode, 
    GraphRelationshipTypes relationshipType, String[] jsonAttributes) { 
StringBuilder sb = new StringBuilder(); 
sb.append("{ \"to\" : \""); 
sb.append(endNode.toString()); 
sb.append("\", "); 

sb.append("\"type\" : \""); 
sb.append(relationshipType.toString()); 
if (jsonAttributes == null || jsonAttributes.length < 1){ 
    sb.append("\""); 
} else { 
    sb.append("\", \"data\" : "); 
    for (int i = 0; i < jsonAttributes.length; i++) { 
     sb.append(jsonAttributes[i]); 
     if (i < jsonAttributes.length - 1){ 
      // Miss off the final comma 
      sb.append(", "); 
     } 
    } 
} 

sb.append(" }"); 
return sb.toString(); 
} 

我的問題是,我想檢查是否給定類型的給定關係的兩個節點之間已經存在PRIOR創建它。

有人可以告訴我,如何查詢關係?

隨着節點我不喜歡這樣的搭配:

MATCH cypher {"statements": [ {"statement": "MATCH (p:SOCIALNETWORK {sn_id: 'TW'}) RETURN p", "resultDataContents":["REST"]} ] } 

對端點

http://localhost:7474/db/data/transaction/<NUMBER> 

我將如何構建,檢查是否有關係的聲明,節點6和5或任何之間說?

由於提前,

克里斯

回答

4

你可能要考慮通過暗號這樣做,並使用MERGE/ON CREATE/ON MATCH關鍵字。

例如,你可以做這樣的事情:

create (a:Person {name: "Bob"})-[:knows]->(b:Person {name: "Susan"}); 

MATCH (a:Person {name: "Bob"}), (b:Person {name: "Susan"}) 
MERGE (a)-[r:knows]->(b) 
ON CREATE SET r.alreadyExisted=false 
ON MATCH SET r.alreadyExisted=true 
RETURN r.alreadyExisted; 

MATCH/MERGE查詢,我在這裏提供將返回true或false,這取決於關係是否已經存在與否。

另外,FWIW它看起來像你用來通過StringBuilder累積JSON的代碼很可能會很笨重和容易出錯。有很多優秀的庫,如Google GSON可以爲你做JSON,所以你可以創建JSON對象,數組,基元等等 - 然後讓庫擔心將它正確序列化爲一個字符串。這往往會使你的代碼變得更清潔,更容易維護,當你把你的JSON格式化(我們都這麼做)的東西搞砸時,比你累積字符串更容易找到。

3

在Java

Relationship getRelationshipBetween(Node n1, Node n2) { // RelationshipType type, Direction direction 
    for (Relationship rel : n1.getRelationships()) { // n1.getRelationships(type,direction) 
     if (rel.getOtherNode(n1).equals(n2)) return rel; 
    } 
    return null; 
} 
+0

喜邁克爾,這個操作快到了很多關於我的。我經常試圖做的是隻在兩個節點不存在的情況下創建兩個節點之間的關係。任何將這個操作包含在neo4j api本身中的機會,或者是否已經包含這個操作的'創建,如果它不存在'? – 2015-04-27 22:09:05