slushpupie
slushpupie

Reputation: 267

How to query nodes exclusively in relationship with certain nodes

I have a graph containing Fruit, Veggie, and Dish node types, with a single relationship type of [:in] to indicate which ingredients are contained in each dish.

Example data:

create (A:Ingredient:Fruit { name: "Apple" }), 
   (B:Ingredient:Fruit { name: "Banana" }),
   (C:Ingredient:Veggie { name: "Cellery" }),
   (D:Ingredient:Veggie { name: "Daikon" }),
   (E:Ingredient:Veggie { name: "Eggplant" }),
   (F:Ingredient:Veggie { name: "Fennel" }),
   (G:Ingredient:Veggie { name: "Gord" }),
   (H:Ingredient:Veggie { name: "Horseradish" }),
   (Salad:Dish { name: "Salad" }),
   (FruitBowl:Dish { name: "FruitBowl" }),
   (Platter:Dish { name: "Platter" }), 
   (StirFry:Dish { name: "StirFry" }), 
   (A)-[:in]->(FruitBowl),
   (B)-[:in]->(FruitBowl), 
   (A)-[:in]->(Platter),
   (B)-[:in]->(Platter),
   (C)-[:in]->(Platter),
   (D)-[:in]->(Platter), 
   (C)-[:in]->(Salad),
   (D)-[:in]->(Salad),
   (E)-[:in]->(Salad),
   (F)-[:in]->(StirFry),
   (G)-[:in]->(StirFry),
   (H)-[:in]->(StirFry)

What I am trying to figure out, is how to query a list of Veggies that only show up in dishes that have only veggies in them. I can get the first part (a list of Dishes that only have veggies) with this query:

match (d:Dish) 
where not ((:Fruit)-[:in]->(d)) 
return d

This returns Salad and StirFry as I expected.

Is there a way to then query all Veggies that only belong to that set? (in this example, only Veggies E,F,G, & H) If not, or if its really hard to do, is there a better way to structure this data to make that apparent relationship more obvious?

Upvotes: 3

Views: 38

Answers (2)

Bruno Peres
Bruno Peres

Reputation: 16375

You are close to the solution. You can match the veggies in the first pattern. The where clause will remove not desired dishes.

match (d:Dish)<-[:in]-(v:Veggie)
where not ((v)-[:in]->(:Dish)<-[:in]-(:Fruit))
return v

the output will be something like:

╒═══════════════════╕
│v                  │
╞═══════════════════╡
│{name: Eggplant}   │
├───────────────────┤
│{name: Horseradish}│
├───────────────────┤
│{name: Gord}       │
├───────────────────┤
│{name: Fennel}     │
└───────────────────┘

Upvotes: 3

Rebecca Nelson
Rebecca Nelson

Reputation: 1296

You can continue your query from the one you started by adding an additional MATCH clause:

MATCH (d:Dish) 
WHERE NOT ((:Fruit)-[:in]->(d))
MATCH (veggie:Veggie)-[:in]->(d)
RETURN (veggie)

Upvotes: 2

Related Questions