I need all nodes which are unique only i.e. even if two or more nodes with same properties exist (in this case it is nodes with name 'B') i need only one node among the duplicate nodes in my search statement (in this case only one 'B' node among the two is to be returned) which would be something like this MATCH (n:PERSON) WHERE [ n.name is unique ] RETURN n.name . Can i know what is the exact query for my requirement ?
3 Answers
If you're only looking for a single result, LIMIT should do the trick:
MATCH (n:Person{name:'B'})
RETURN n LIMIT 1
If you're looking up based on multiple rows, such as an input collection, then you only want a single result per row, so you can collect and take the first result:
UNWIND ['A','B','C'] as name
MATCH (n:Person {name:name})
WITH name, head(collect(n)) as n
RETURN n
If you have access to APOC Procedures you can also use APOC aggregation functions instead:
UNWIND ['A','B','C'] as name
MATCH (n:Person {name:name})
WITH name, apoc.agg.first(n) as n
RETURN n
The cypher equivalent of MATCH (n:PERSON) WHERE [ n.name is unique ] RETURN n.name
would simply be MATCH (n:PERSON) RETURN DISTINCT n.name
. RETURN DISTINCT
filters out any duplicate row results. If you returned the node, RETURN DISTINCT would not work because the different internal node id's would make the 2 rows distinct from each other.
Now, assuming that you do want to return the nodes, but want to ignore their internal ID, you will need to do something like this...
MATCH (n)
// Collect results into one list for filtering
WITH COLLECT(n) as ns
RETURN FILTER(n IN ns
WHERE NONE(
// Remove nodes that share all properties
PROPERTIES(n)=PROPERTIES(x) AND
// But keep 1 instance. In this case, the one with the lowest ID
x in ns WHERE ID(x) < ID(n)
)) as ns