2017-12-21 2 views
0

사이퍼에서 조건부 쿼리를 실행하려고합니다. 아래 예제는 내 예제 쿼리이지만 조건이 true 인 경우에도 새 대화 노드를 만들지 않습니다.apo를 사용하는 neo4j의 조건부 쿼리

WITH ["Ram", "Shyam", "Hari"] as names 
WITH names, size(names) AS requiredCount 
MATCH (u:User) WHERE u.name IN names 
WITH u, requiredCount 
MATCH (u)-[:IS_PARTICIPANT]->(c:Conversation) 
WITH requiredCount, c, u, count(u) as matches 
WHERE requiredCount = matches and size(()-[:IS_PARTICIPANT]->(c)) = requiredCount 
WITH u, count(c) as conversationExists 
CALL apoc.do.when(conversationExists < 1, 'MERGE (cc:Conversation {_id: 
apoc.create.uuid(), createdAt: timestamp()}) RETURN cc', '', {u: u}) YIELD value 
RETURN value 

답변

1

여기에는 몇 가지 문제가 있습니다.

names은 두 번째 줄의 WITH에 있어야합니다 (실수로 userIDs으로 이름을 바꾼 것 같습니다).

귀하는 WITH requiredCount, c, u, count(u) as matches을 보유하고 있으며 귀하가 생각하는대로하지 않습니다. 집계 함수에는 그룹화 키를 형성하는 비 집계 컬럼의 컨텍스트가 있습니다. 그것은 다음과 같이 그것을 읽는 것을 도울 수 있습니다 : "for each requiredCount, c, and u, for that count of that". 1 행당 1 u 만 있으므로 모든 행에 대해 matches 카운트가 항상 1이되므로 이름 컬렉션이 1보다 클 때마다 쿼리가 항상 실패합니다. 해당 행에 대해 WITH RETURN을 변경하여 직접 테스트 할 수 있습니다. 나머지는 주석으로 처리합니다. u을 수집하거나 해당 행에서 제거하여 다르게 처리해야합니다.

무언가와 일치하지 않는 MATCH를 수행하거나 WITH 절로 WHERE 절을 사용하는 것은주의해야합니다. WITH 절은 모든 행을 삭제하면 쿼리를 계속할 수 없기 때문입니다 (기본적으로 MATCH와 WHERE가 실패하면이 행에 전혀 도달 할 수 없습니다 : WITH u, count(c) as conversationExists). OPTIONAL MATCH를 사용하거나 WHERE 절을 WITH 절의 부울 변수로 추출 할 수 있습니다.

+0

마지막으로 필자는 WITH와 WHERE의 한 가지 질문을 이해합니다.하지만 WITH '(userCnt = inputCnt AND size (() - [: IS_PARTICIPANT] -> (c)) = inputCnt) 사용자의 모든 대화가 올바 릅니까? 나는 값이 비쌀 것입니다. 그래서 저는 두 가지 질문을했습니다. 첫 번째 대화는 사용자간에 대화가 있는지 확인하고 두 번째 대화 대화 상자가없는 경우 대화 대화 노드를 만듭니다. – Yalamber

+0

WITH 절은 주어진 사용자의 대화 (모든 사용자가 아님)와 [size() 검사가 효율적입니다] (https://neo4j.com/developer/kb/how-do-i-improve 노드상의 관계 수를 계산하는 성능; 실제로 관계를 확장 할 필요없이 대화 노드에서 IS_PARTICIPANT 관계의 정도를 얻습니다. – InverseFalcon

+0

WHERE 또는 WITH를 사용하는 것에 대해 우려했습니다. WHERE 또는 WITH를 사용하면 동일한 쿼리 비용이 발생합니까? – Yalamber