2014-11-23 4 views
1

이 Cypher Query를 neo4jclient으로 변환하는 데 도움이 될 수 있습니까?Neo4jClient Union

MATCH (o)-[r]-(post:Post)-[:HAS_MentionedUsers]->(assignee1307989068:User), 
WHERE (assignee1307989068.UserName = "mhs") 
RETURN post,o,r 
UNION 
MATCH (o)-[r]-(post:Post)-[:HAS_HashTags]-> (Hashtag1841024507:HashTag) 
WHERE (Hashtag1841024507.Value = "myTag") 
RETURN post,o,r 

neo4jClient "MHS"와 C#에서 "myTag"와 수 whould 동적으로 사용자 입력에 따라 위의 사이퍼 쿼리를 만드는 방법에 어떤 아이디어가 있습니까? 여기

는 지금까지 havetried 것입니다 :

검색 방법은 검색어를 얻고 사이퍼 쿼리의 각 부분을 추가 할 방법을 BuildPostQueystring 다음을 토큰 화합니다.

public Object Search(string searchterm) 
    { 
     List<string> where = new List<string>(); 
     var tokenizedstring = searchterm.Split(' '); 
     var querystring = new StringBuilder(); 
     int unionCount = 0; 
     var q = new CypherFluentQuery(_graphClient) as ICypherFluentQuery; 

     foreach (var t in tokenizedstring) 
     { 
      _commandService.BuildPostQueystring(t, ref querystring, ref where); 

      if (querystring[querystring.Length - 1] == ',') 
       querystring = querystring.Remove(querystring.Length - 1, 1); 

      if (unionCount > 0) 
       q = q.Union(); 


      q = q.Match(querystring.ToString()); 

      unionCount++; 

      int i = 1; 

      if (where.Count > 0) 
       q = q.Where(where[0]); 

      while (i < where.Count) 
      { 
       q = q.OrWhere(where[i]); 
       i++; 

      } 

      q = q.Return((post, nodes) => new { Post = post.As<Node<string>>(), Nodes = nodes.As<Node<string>>() }) 
      .OrderBy("post.creationDate"); 

      where.Clear(); 
      querystring.Clear(); 
     } 

     //var rq = q.Return((post, o) => new {Person = post.As<Node<string>>(), Dog = o.As<Node<string>>()}) 
     // .OrderBy("post.creationDate"); 

     var x = (q as CypherFluentQuery<dynamic>).Results; 

     return x.ToList(); 
    } 

쿼리 부분을 추가 할 다른 방법은 휴입니다 :

public void BuildPostQueystring(string token, ref StringBuilder sb, ref List<string> whereConditions) 
    { 
     string querystring = "(nodes)-[r]-(post:Post)-[:HAS_{0}]->({1}:{2})"; 
     string wherestring = "({0}.{1} = \"{2}\")"; 
     if (token.StartsWith("#")) 
     { 
      int hash = token.GetHashCode(); 
      if (hash < 0) 
       hash = hash*-1; 

      string paramName = "Hashtag" + hash; 
      var str = string.Format(querystring, "HashTags", paramName, "HashTag"); 
      var tvalue = token.Replace("#", ""); 
      //query = query.AndWhere((HashTag hashTag) => hashTag.Value == tvalue); 
      sb.Append(str); 
      whereConditions.Add(string.Format(wherestring, paramName, "Value", tvalue)); 
     } 

     else if (token.StartsWith("+")) 
     { 

      int hash = token.GetHashCode(); 
      if (hash < 0) 
       hash = hash * -1; 
      string paramName = "team" + hash; 

      var str = string.Format(querystring, paramName, "MentionedTeam","Team"); 
      sb.Append(str); 
      var tvalue = token.Replace("+", ""); 
      whereConditions.Add(string.Format(wherestring,paramName, "Name", tvalue)); 
     } 

     else if (token.StartsWith("@")) 
     { 
      int hash = token.GetHashCode(); 
      if (hash < 0) 
       hash = hash * -1; 

      string paramName = "assignee" + hash; 

      var str = string.Format(querystring, "MentionedUsers", paramName, "User"); 
      sb.Append(str); 
      var tvalue = token.Replace("@", ""); 
      whereConditions.Add(string.Format(wherestring, paramName,"UserName", tvalue)); 
     } 
     else if (token.StartsWith("by")) 
     { 
      int hash = token.GetHashCode(); 
      if (hash < 0) 
       hash = hash * -1; 

      string paramName = "author" + hash; 

      var str = string.Format(querystring, "Author", paramName, "User"); 
      sb.Append(str); 

      var tvalue = token.Replace("by:", ""); 
      whereConditions.Add(string.Format(wherestring, paramName, "UserName", tvalue)); 

     } 
     else if (token.Contains("\\")) 
     { 
      foreach (var dt in GetLocalDateTokens(_dateTimeTokens)) 
      { 
       int hash = token.GetHashCode(); 
       if (hash < 0) 
        hash = hash * -1; 

       string paramName = "dueDate" + hash; 

       if (token.ToLower() == dt.Text.ToLower()) 
       { 
        var neodate = new NeoDateTime(); 
        neodate.Year = dt.GetDate.Year; 
        neodate.Month = dt.GetDate.Month; 
        neodate.Day = dt.GetDate.Day; 
        neodate.TimeStamp = long.Parse(dt.GetDate.ToString("HHmmss")); 
        neodate.DateStamp = long.Parse(dt.GetDate.ToString("yyyyMMdd")); 
        neodate.DateTimeStamp = long.Parse(dt.GetDate.ToString("yyyyMMddHHmmss")); 
        var str = string.Format(querystring, "DueDates", paramName, "NeoDateTim"); 
        sb.Append(str); 
        var tvalue = token.Replace("by:", ""); 
        whereConditions.Add(string.Format(wherestring, "DateStamp", paramName, tvalue)); 

       } 
      } 
     } 
     else 
     { 
      //MATCH (n) 
      //WHERE n.name =~ 'Tob.*' 
      //RETURN n 
      var wherestr = "({0}.{1} =~ '{2}.*')"; 
      //string wherestring = "({0}.{1} = \"{2}\")"; 
      //string querystring = "(post:Post)-[:HAS_{0}]->({1}:{2})"; 
      string paramName = "post" + token + GetHashCode(); 
      string qs = "(post:Post)"; 
      var str = string.Format(qs, paramName); 
      sb.Append(str); 
      whereConditions.Add(string.Format(wherestr, "post", "Text", token)); 

     } 
     if(sb.Length>0) 
      sb.Append(","); 


    } 

내 첫 번째 문제는 q는 결과 방법이 없으며 내가 그것을 캐스팅 어차피 같은 결과를 얻는 방법이다 익명의 유형?!

+0

오케이, 지금까지 시도한 것은 무엇입니까? –

+0

내가 시도한 것은 휴경이다 : 1- 나는 검색 입력을 토큰 화한다. 2 포스트에 일치 문자열을 만든다. 문자열의 끝에 Where 절을 추가한다. 4- 결과를 얻는다. 5- 결과를 얻는다. 뒤로. 내가 지금까지 가지고있는 문제는 내가 (o) - [r] 에 의해 캡처하려고하는 POST에 다른 모든 관련 노드를 잃어 버리고 있다는 것입니다. where where 절을 추가하면 결과가 달라집니다. 또는 함께 또는 각각의 결과 섹션을 결합하는 경우. –

답변

2

확인, 먼저, 이유 q은 때까지 당신이 단지 ICypherFluentQuery을 부르는 Return를 추가하기 때문에 Results 방법이 없습니다, 그래서 당신이있는 경우 :

var query = client.Cypher.Match("(n:Post)"); 

query 유형이 될 것입니다 당신이 Return 문 추가하면되는 ICypherFluentQuery가하는 Results 방법을 가지고 있지 않습니다

var query = client.Cypher.Match("(n:Post)").Return(n => n.As<Post>()); 

당신이 query을 찾을 지금이다 : ICypherFluentQuery<Post>. 당신이 당신의 .Return 문을 추가하기 전에 그래서, 당신은 다른 변수에 할당해야합니다

var query = client.Cypher.Match("(n:Post)"); 
var retQuery = query.Return(n => n.As<Post>()); 
var results = retQuery.Results; 

두 번째 부분, 실제 쿼리를.

그것은 당신이 당신의 코드와 함께 일을하려고하는지 완전히 명확하지, 당신은 그것을 많이 가지고 있지만, (내 생각에) 쿼리에 대한 코드는 다음과 같이 보일 것입니다 :

private void GetResults(string username, string tagValue) 
{ 
    var query = Client.Cypher 
     .Match("(o)-[r]-(post:Post)-[:HAS_MentionedUsers]->(assignee:User)") 
     .Where((User assignee) => assignee.UserName == username) 
     .Return((post, o, r) => new {Post = post.As<Post>(), O = o.As<object>(), R = r.As<RelationshipInstance<object>>()}) 
     .Union() 
     .Match("(o)-[r]-(post:Post)-[:HAS_MentionedUsers]->(hashTag:HashTag)") 
     .Where((HashTag hashTag) => hashTag.Value == tagValue) 
     .Return((post, o, r) => new {Post = post.As<Post>(), O = o.As<object>(), R = r.As<RelationshipInstance<object>>()}); 

    var res = query.Results.ToList(); 
} 

PS : 나는 타입 o이 무엇인지 모른다, 그래서 나는 자리로 object을 사용했다

당신이 다음 서사시 쿼리를 구축하고 당신이 그 이름 assignee1307989068 등을 사용할 필요가 어떤 이유로하는 경우당신이 할 수있는 경우는 안전하고 이해하기 쉽게 입력입니다, 나는 첫 번째 버전으로 갈 것

/* MATCH */ 
.Where("assignee123.Value == {assignee123Param}") 
.WithParam("assignee123", username) 
/* RETURN */ 

: 561,뭔가처럼 될 것입니다.

+0

크리스 (Chris)님께, 귀하의 요점은 무엇입니까? 내 코드가 복잡하다는 이유는 (#, @, +, /와 같은 멋진 문자로 장식 된 사용자 입력을 얻고 있으며 어떤 문자가 사이퍼 쿼리에 포함되어야하는지 찾을 수 있기 때문입니다. 항상 해시 태그 및 사용자는 아닙니다. FluentcypherQuery가 return 유형의 T 비트를 얻을 때 그 결과가 유용 할 것이라는 것을 이해합니다. 우리는 neo4jclient에서 json 결과를 얻는 방법이어야한다고 생각합니다. –

+0

나는 json 결과를 반환하도록이 게시물을 찾았습니다. http://stackoverflow.com/questions/21860074/casting-nodes-of-an-unknown-type 하지만 정말 감사합니다. 이 주제들. –