2016-10-02 3 views
0

다음 쿼리를 사용하여 두 카운트의 차이를 계산하려고합니다.CYPHER - 서로 다른 COUNT가 동일한 결과를 반환합니다.

MATCH (user: User {username : 'bar' }) 
MATCH (user)-[upvote : UPVOTED]->(:Post) 
MATCH (user)-[downvote : DOWNVOTED]->(:Post) 
RETURN COUNT(upvote) - COUNT(downvote) 

두 카운트가 모두 동일하므로 항상 0을 반환합니다. 각 계산에 대해 별도로 쿼리를 실행했지만 실제로는 서로 다릅니다 (3과 1). 그러나 쿼리를 수행하면 좋지 않은 결과가 반환됩니다.

[업데이트]

이상하게,이 쿼리 예상 출력이 MATCH 큰이 결과

을 지배하는 것처럼 그것은 1. 동안 그것은, 3 반환

MATCH (user : User {username : 'bar' }) 
MATCH (user)-[upvote : UPVOTED]->(:Post) 
MATCH (user)-[downvote : DOWNVOTED]->(:Post) 
RETURN COUNT(downvote) 

을 실행할 때

아이디어가 있으십니까? 감사합니다.

+0

'COUNT'을 (를) 추가하기 전에 * 해당 쿼리의 결과를 살펴 보았습니까? 실제로 일치하는 항목을 알고 있습니까? 그 이유를 알 수 있습니다. – jonrsharpe

+0

나는 매치를 개별적으로 테스트했으며리스트를 반환한다. upvotes 3 항목과 downvotes 1 항목. 두 일치 항목을 모두 사용하여 쿼리를 실행하면 각각에 3 개의 항목이있는 두 목록이 반환됩니다. 관계에 속성이 없기 때문에 이러한 반환 된 항목의 내용을 확인할 수 없습니다. –

+0

그리고 그들 각각의 수는 무엇입니까? 4? – jonrsharpe

답변

3

Neo4j는 MATCH 및 OPTIONAL MATCHES를 수행 할 때 행을 작성합니다. 이전 쿼리의 결과 수에 따라 달라집니다.

예를 들어

,의 사용자가 3 upvoted하지만 upvotes에 대한 MATCH의 끝에서 1

을을 downvoted했다고 가정 해 봅시다, 행의 수는 사용자와의 3 각되어 구축되고, 각각 upvoted 관계. 사용자의 upvotes 중 하나, 그리고 하나의 downvote :의

user, up1, down1 
user, up2, down1 
user, up3, down1 

카운트를, 행의 개수가 건설되고

그러나 downvotes에 대한 일치의 끝에

은 각 행이 3입니다 ups는 정확해야하지만 downs 수는 3이 될 것입니다.

이것은 성능에 영향을 미친다는 점에 유의하십시오. 사용자에 대한 하향 투표를 얻는 쿼리는 단일 사용자에 대해 한 번만 실행되지만 사용자가있는 각 행에 대해 한 번 (3 회) 각 행에서 동일한 사용자가되는 경우).

당신이 2 downvotes 대신 중 하나를 가지고 있다면, 다음 6 구축 행 (3 × 2, 각각의 가능한 downvote와 짝을 각 upvote에)있을 것입니다 : 당신이 한 경우

user, up1, down1 
user, up1, down2 
user, up2, down1 
user, up2, down2 
user, up3, down1 
user, up3, down2 

DISTINCT 업의 수 그리고 DISTINCT가 끝나면 오른쪽 숫자를 얻어야하지만 더 좋은 방법은 첫 번째 일치가 두 개 이상의 행을 결과로하는 곳을 찾는 것을 배제하고 이처럼 일찍 계산을하는 것입니다 :

MATCH (user : User {username : 'bar' }) 
MATCH (user)-[upvote : UPVOTED]->(:Post) 
WITH user, COUNT(upvote) as upvotes 
MATCH (user)-[downvote : DOWNVOTED]->(:Post) 
RETURN upvotes, COUNT(downvote) as downvotes 

이유는 다음과 같은 이유 때문입니다. 중간, 당신은 upvote 카운트와 함께 1 행을 구축했습니다 : 사용자. 우리가 downvotes에 일치하는 경우, 구축 행은 각 downvote 관계 카운트 upvote에와 사용자가 될 것입니다 :

user, 3 as upvotes, down1 
: 당신은 COUNT 함수를 실행할 때 당신에게 정확한 수를 얻을 것이다 downvotes X 1, 수 당신은 하나가 아닌 두 downvotes이 있다면

, 그것은 다음과 같습니다 등등

user, 3 as upvotes, down1 
user, 3 as upvotes, down2 

그리고있다.

일반적으로 할 수있는 경우, 종단 대신 연속적 매치 또는 선택적 매치간에 집계 (집계, 수집 등)를 수행하십시오 (물론 자신이하는 일을 알지 못하는 한 귀하의 경우에 맞춰 일치하는 것이 맞습니다). neo4j가 어떻게 행을 구성하는지 시각화하십시오. 그러면 잘못 될 수있는 것에 대해 단서가 생깁니다.

관련 문제