Need help with a query

Hello everyone, I am relatively new at Neo4j, but I am working on a side project for myself. I am not sure if my modeling is wrong, but here is what I am doing.

What I have done is to take a list of food products, in this screenshot, the product shown is "Tutturos...", and then I have broken out all the ingredients for that product and made a "contains" relationship. So, as shown, the product contains "citric acid", "natural flavor"...and so forth. The two node labels are Products and Ingredient.

However, I am struggling with writing a query that says "get me all the products that contains citric acid AND natural flavor" for example.

I tried this:

match (p:Product)-[r:contains]->(i:Ingredient)
where i.name = 'citric acid'
and i.name = 'natural flavor'
RETURN p

But it returns no records because it is probably saying there are no nodes with ingredient natural flavor as well as citric acid at the same time, resulting in an impossible query. In other words, I know why the query above doesn't work, but I can't figure out how to make it work.

It could be that my modeling is wrong. But I do want a way to link individual ingredient items to a product so a search can be made on multiple exact ingredient items.

Thanks in advance for your help.

[edit] Upon further research it seems as if my problem is how I have modeled this. I am guessing a node shouldn't have multiple relationships of the same type (in my case one node has multiple "contains" relationship to ingredients). Am i right?

I think you can do it like this:

match (p:Product)-[r:contains]->(i1:Ingredient {name: "citric acid"}),
           (p:Product)-[r:contains]->(i2:Ingredient  {name: "natural flavor"})
RETURN p

Or for a more generic version:

with ["citric acid", "natural flavor"] AS ingredients
match (p:Product)
where all(i in ingredients WHERE exists((p)-[r:contains]->(:Ingredient  {name: i})))
RETURN p

The issue with the original query is that it effectively says:

Find me paths where there's an Ingredient node that has a name property with the value citric acid and the value natural flavor, which isn't possible!

2 Likes

Try this. Replace 'and' with 'or' :

match (p:Product)-[r:contains]->(i:Ingredient)
where i.name = 'citric acid'
or i.name = 'natural flavor'
RETURN p

Try to use below query,
match (p:Product)-[r:contains]->(i:Ingredient)
where i.name = 'citric acid.' and i.name = 'natural flavor'
RETURN p

as per the image your ingredient name is "citric acid." but in the query you missed "."

Thanks for your reply. Both these options worked. I had started to think that maybe I should add the ingredients as an array property to product. Do you think that would be a better option than using the contains relationship?

Thanks! However replacing and with or, gives me one or the other ingredient and I needed the product to have both ingredients. Mark Needham's reply worked for me,