Do not return set of nodes from a specific path in Cypher

57 Views Asked by At

I am trying to return a set of a node from 2 sessions with a condition that returned node should not be present in another session (third session). I am using the following code but it is not working as intended.

MATCH (:Session {session_id: 'abc3'})-[:HAS_PRODUCT]->(p:Product)        

UNWIND ['abc1', 'abc2'] as session_id
MATCH (target:Session {session_id: session_id})-[r:HAS_PRODUCT]->(product:Product)
where p<>product

WITH distinct product.products_id as products_id, r
RETURN products_id, count(r) as score
ORDER BY score desc

This query was supposed to return all nodes present in abc1 & abc2 but not in abc3. This query is not excluding all products present in abc3. Is there any way I can get it working?

UPDATE 1: I tried to simplify it without UNWIND as this

match (:Session {session_id: 'abc3'})-[:HAS_PRODUCT]->(p:Product)
MATCH (target:Session {session_id: 'abc1'})-[r:HAS_PRODUCT]->(product:Product)
where product <> p
WITH distinct product.products_id as products_id
RETURN products_id

Even this is also not working. It is returning all items present in abc1 without removing those which are already in abc3. Seems like where product <> p is not working correctly.

1

There are 1 best solutions below

0
On

I would suggest it would be best to check if the nodes are in a list, and to prove out the approach, start with a very simple example.

Here is a simple cypher showing one way to do it. This approach can then be extended into the complex query,

// get first two product IDs as a list
MATCH (p:Product)
WITH p LIMIT 2
WITH COLLECT(ID(p)) as list
RETURN list

// now show two more product IDs which not in that list
MATCH (p:Product)
WITH p LIMIT 2
WITH COLLECT(ID(p)) as list
MATCH (p2:Product)
WHERE NOT ID(p2) in list
RETURN ID(p2) LIMIT 2

Note: I'm using the ID() of the nodes instead of the entire node, same dbhits but may be more performant...