2014-12-01 3 views
0

나는 나가는 관계 수량으로 큰 데이터베이스를 정렬하고 있습니다. 다음과 같이 작동하는 Cypher 쿼리가 있습니다.Neo4jClient에서 OrderBy 활용 문제

optional match (n)-[r]->(m) 
return n, Count(r) as c 
order by c DESC limit 1; 

Cypher 쿼리가 예상대로 작동합니다. 그러나 Cypher -> Neo4jClient 변환을 디버깅하고 진행하면서 문제의 근원을 찾을 수없는 것 같습니다.

public ReturnPayload[] getByConnections() 
    { 
     var query = client.Cypher 
      .OptionalMatch("(p)-[r]->(m)") 
      .Return((p, r, m, c) => new 
      { 
       p = p.As<Person>(), 
       pid = (int)p.Id(), 
       e = r.As<RelationshipInstance<Object>>(), 
       m = m.As<Metadata>(), 
       c = r.Count() 
      }).OrderByDescending("c").Limit(1); 

     var res = query.Results; 
     var payload = new List<ReturnPayload>(); 
     foreach (var el in res) 
     { 
      var t = new ReturnPayload(); 
      t.e = el.e; 
      t.m = el.m; 
      t.pid = el.pid; 
      t.p = el.p; 
      payload.Add(t); 
     } 

     return payload.ToArray<ReturnPayload>(); 
    } 

나는 문제의 일부가 나는 CollectAs<T>()를 사용하고 있지 않다 따라서는 각 사람마다 '1'의 수를 언급하고 있음을 수 있다는 것을 생각한다. 불행히도 CollectAs<T>()CollectAsDisctinct<T>()을 사용하여 시도했으며 결과 JSON 아키텍처는 동일한 요소를 적절한 배열로 집계하는 것과는 대조적으로 배열의 각 요소 만 래핑합니다.

FOREACH 루프는 익명 유형을 매개 변수 내에서 c 개체를 사용하지 않는 비교적 표준 인 <ReturnPayload>으로 변환하는 데 도움이됩니다.

시간 내 주셔서 감사합니다. 감사합니다.

디버깅 쿼리 테스트 :

OPTIONAL MATCH (p)-[r]->(m) 
RETURN p AS p, id(p) AS pid, r AS e, m AS m, count(r) AS c 
ORDER BY c DESC 
LIMIT {p0} 

그리고 내 '기능'사이퍼 쿼리

optional match (n)-[r]->(m) 
return n, Count(r) as c 
order by c DESC limit 1; 
+0

https://github.com/Readify/Neo4jClient/wiki/cypher#debugging에 따라 디버그 쿼리 텍스트를 가져와 예상/작동중인 쿼리와 비교할 수 있습니까? –

+0

@TathamOddie : 나쁘다. 초기 게시물의 맨 아래로 편집하십시오. – Kyle

+0

@TathamOddie : Cypher 창에서 디버깅 된 쿼리를 실행하면 잘못된 (논리적으로 코드 오류가 발생하지 않음) 데이터가 생성됩니다. 따라서 Cypher 쿼리는 유효하지만 Cypher 구문은 유효하지 않습니다. – Kyle

답변

1

그래서, 당신은 당신이 두 개의 서로 다른 쿼리를 실행하는 것이 자신을 확인했습니다. 이것은 문제입니다. C#이 예상 한 Cypher와 일치하지 않습니다.

이로 변경,는 C# 일치 작업 사이퍼하게하려면 다음 작업 사이퍼에서 기다리고있어 지금처럼 동일한 쿼리를 생성하고, 따라서 동일한 출력한다

var query = client.Cypher 
     .OptionalMatch("(n)-[r]->(m)") 
     .Return((n, r) => new 
     { 
      n = n.As<Person>(), 
      c = r.Count() 
     }) 
     .OrderByDescending("c") 
     .Limit(1); 

.

순전히 문체 노트에, 당신은 또한 더 많은 기능 동등한에 foreach 쿼리를 단순화 할 수 있습니다 :

var payload = query 
    .Results 
    .Select(r => new ReturnPayload { 
     n = r.n, 
     c = r.c 
    }) 
    .ToArray(); 
return payload; 

을하지만, 당신의 쿼리와 가까이 보면 당신은 단지의 수를 원하는처럼 보이는 톱 1을 얻으 려다가 그걸 던져 버릴거야.

WITH 절 사용을 고려 :

optional match (n)-[r]->(m) 
with n as n, count(r) as c 
order by c desc 
limit 1 
return n 

당신은 그 뒤로 C# 사용하여 유사한 구문을 매핑 할 수 있습니다 : 다음

var query = client.Cypher 
    .OptionalMatch("(n)-[r]->(m)") 
    .With((n, r) => new 
    { 
     n = n.As<Person>(), 
     c = r.Count() 
    }) 
    .OrderByDescending("c") 
    .Limit(1) 
    .Return(n => new ReturnPayload  // <-- Introduce the type here too 
    { 
     n = n.As<Person>() 
    }); 

을, 당신은 데이터를 쿼리하고 그냥 던져 필요가 없습니다 멀리 다른 foreach 루프. (Return 호출에서도 DTO 유형을 소개하므로 익명 유형을 번역 할 필요가 없습니다.

(면책 조항 :이 C#을 모두 입력하기 만하면됩니다. 대답에 곧바로 나는 컴파일을 두 번 확인하지 않았으므로 서명이 약간 벗어날 수 있습니다.)

희망이 있습니다!

+0

감사합니다. 내 유일한 질문은 두 가지 사이퍼 쿼리간에 결과가 왜 크게 다른 이유입니까? 지금까지 보았 듯이 '기능적'쿼리는 반환을 통해 전달되는 변수가 더 많습니다. 주문했을 때 그와 같은 예기치 않은 동작이 나타나는 이유는 무엇입니까? – Kyle