How to find nodes with 0 relationships with?

I want to find brand nodes that don't have any hasBrand relationship with products:

match (n:Product) -[r:hasBrand] ->(brand) with count(brand) as brands where brands <1 return brand.name

It gives this error message:

Variable `brand` not defined (line 1, column 97 (offset: 96))
"match (n:`_product`) -[r:hasBrand] ->(brand) with count(brand) as brands where brands <1 return brand.name"

Do you have a Brand label on Brand nodes? If so, would this work for you?

MATCH (b:Brand)
WHERE NOT (b)<-[:hasBrand]-(:Product)
RETURN b.name?

In your query you did not group by brand and also count should be for relationship

Try

match (n:Product) -[r:hasBrand] ->(brand) with brand, count(hasBrand) as brands where brands <1 return brand.name

Error message: Variable 'hasBrand' not defined. I changed 'hasBrand' to 'r', then it found 0 nodes, which is not true. So probably this query still isn't doing the right thing.

My mistake try like below

match (n:Product) -[r] ->(B:Brand) with B, type(r) as rel ,count(r) as brands where rel <> 'hasBrand' return B, rel,brands

from a performance perspective I would expect the following to be the fastest

match (b:Brand)
where size (  (b)-[:hasBrand]->() ) = 0
return b

what this does is iterate over all :Brand nodes, for each node check the pre-computed metadata which holds the number of relationships by type and direction and report the :Brand where there are no :hasBrand relationships.

Usage of count(hasBrand) etc, will cause Neo4j to iterate over each relationship and check its type.

For example if you have 1 :Brand and it has 50 :hasBrand relationships, the usage of size ( ..... ) should result in 1 dbhit to get the result. Whereas if you count(hasBrand) this this would result in 51 dbhits

1 Like

Those are good options and thank you.