2017-10-26 8 views
1

좋아, 그래서 여기에 내 데이터 모델이다. 각 사용자의 계정은 :ASSIGNED_TO이고 위치는 :ASSIGNED_TO입니다. 위치는 :BELONGS_TO입니다.얻기 잘못된 값이

나는 특정 계정을 ID로 선택하려고 시도하고 있으며 해당 계정의 사용자 및 위치 수를 반환하려고합니다.

MATCH (account:Account) 
WHERE account.id = '123456' 
WITH account 
OPTIONAL MATCH (location:Location)-[:BELONGS_TO]->(account) 
OPTIONAL MATCH (user:User)-[:ASSIGNED_TO]->(account) 
RETURN account, count(location) as locationCount, count(user) as userCount 

이 결과는 account하는 userCount = 16 (correct)locationCount = 16 (incorrect; should be 1)입니다 : 여기 내 쿼리입니다. 위치 카운트 에 distinct을 추가하면 정확한 결과 (1)가 표시되고 사용자의 OPTIONAL MATCH을 제거하면 위치 카운트 1을 얻게됩니다. 사용자 수와 관련이 있다는 것을 알고 있습니다. 관계를 계정 및 위치와 비교하지만 별개의 쿼리가 작동하지 않는 이유를 이해하려고합니다. 또한 이것을 작성하는 더 좋은 방법이 있습니까?

답변

1

사실 약간 까다 롭습니다. 이것은 당신이 찾고있는 패턴을 보여주기 위해 다시 쿼리입니다 :이 중간에 하나 개의 계정은, 그러나 당신이 숫자는 각면에있는 모르는

MATCH (account:Account) 
WHERE account.id = '123456' 
MATCH (location:Location)-[:BELONGS_TO]->(account)<-[:ASSIGNED_TO]-(user:User) 
RETURN account, count (location), count (user) 

. 결과 집합에는 패턴에 대한 모든 일치 항목이 포함됩니다 (16 번이지만 더 많은 위치와 사용자가 여러 위치에 할당되었을 수 있음). 그래서 실제로 도 맞지 않습니다 (사용자에게 운이 좋은 것입니다).

MATCH (account:Account) 
WHERE account.id = '123456' 
MATCH (location:Location)-[:BELONGS_TO]->(account)<-[:ASSIGNED_TO]-(user:User) 
RETURN account, count (DISTINCT location), count (DISTINCT user) 

DISTINCT가 문제를 해결합니다. 계정별로 집계 (하나의 실제 집계가 발생하지 않음) 결과 집합에 16 개의 위치가 있습니다. DISTINCT는 고유 한 것만 계산하도록합니다. 그리고 동일한 DOES가 사용자에게도 적용됩니다! 이 도움이

MATCH (account:Account) 
WHERE account.id = '123456' 
MATCH (location:Location)-[:BELONGS_TO]->(account) 
RETURN account.id as id, "location count" as type, count(location) as ct 
UNION 
MATCH (account:Account) 
WHERE account.id = '123456' 
MATCH (account)<-[:ASSIGNED_TO]-(user:User) 
RETURN account.id as id, "user count" as type, count(user) as ct 

희망 :

차이를 보려면이 쿼리에서 살펴 보자.

감사합니다, 톰

+0

입니다. 답장을 보내 주셔서 감사합니다. 내가 쿼리를 작성한 이유는 (사용자 및 위치에 대한 별도의 선택적인 MATCH 문) 동적으로 생성 되었기 때문입니다. 나는 'withUsers'와 'withLocations'를 가지고 독립적으로 설정할 수 있으므로 최종 쿼리에서 둘 중 하나 또는 둘 다를 가질 수 있습니다. 나는 '뚜렷한'작품을 얻었고, 왜 데이터베이스에 하나만있을 때 16 개의 위치가 반환되는지 이해하려고 노력하고 있습니다. 나는 그것이 16 명의 사용자와의 관계와 관련이 있다고 생각하지만, 그것이 왜 그런지 알지 못합니다. – Jason

+0

카운트를 결정하는 전체 패턴 (계정별로 그룹화), 일치하지 않는 (!!!) 사용자 또는 위치에 대한 일치 횟수입니다. 만약 20 번의 안타를 발견한다면 당신의 카운트는 20이 될 것입니다. –

0

결과를 그래프가 아닌 행으로 보면 실제로 16 행의 데이터가 있음을 알 수 있습니다. 각 행에는 location이 포함되어 있으며 은 실제로 location 인 행 수를 반환합니다.

나는 중복을 제거하기 위해 distinct을 사용하는 것을 선호합니다. 프로덕션 환경에서 서비스를 제공하며 유사한 시나리오에서 distinct을 사용하고 있습니다.

0

나는 비슷한 문제에 직면하고 그것이 RDBMS의 관점에서 생각하는 것을 도왔다.

과 같이 사용자의 테이블 (내 예를 들어 4를 사용합니다) 고려 :

Users 
----- 
u1 
u2 
u3 
u4 

을 그리고 위치의 두 테이블을 고려하고 계정 각 (하나 개의 레코드 각, 귀하의 경우와 같은) : 이제

Locations 
--------- 
loc1 

Accounts 
-------- 
acc1 

, Neo4j는 MATCH (location:Location)-[:BELONGS_TO]->(account)<-[:ASSIGNED_TO]-(user:User) 같은 쿼리를 평가할 때, 그것은 User 노드 및 Location 노드를 찾고 시작하고, 그 다음 조인을 수행 Account 노드에 안쪽 관계를 다음과 같습니다. 따라서 해당 쿼리를 중간 쿼리로 나누려면 MATCH (location:Location)-[:BELONGS_TO]->(account)MATCH (account)<-[:ASSIGNED_TO]-(user:User)과 같이 표시됩니다. 그 2 개 쿼리를 평가하면 다음 표와 같이 우리에게 뭔가를 줄 것입니다 : 당

User-Account-Location 
--------------------- 
u1 | acc1 | loc1 
u2 | acc1 | loc1 
u3 | acc1 | loc1 
u4 | acc1 | loc1 

count(location) : 마지막으로

Location-Account 
---------------- 
loc1 | acc1 

Account-User 
------------ 
u1 | acc1 
u2 | acc1 
u3 | acc1 
u4 | acc1 

, Neo4j는이 중간 결과를 조인 다음 결합 된 테이블 같은 것을 반환하는 수행 이 테이블은 count(DISTINCT(location))이 1이되는 반면 4는