cancel
Showing results for 
Search instead for 
Did you mean: 

Trying to create a recipes graph by importing collection from MongoDB

My goal is to connect a MongoDB database of different recipes with Neo4j and create a graph with the recipes and their corresponding ingredients.

I am using Neo4j Desktop version 1.3.4, and would like to read some documents from a collection in MongoDB. Each document would look like the following:

{"id": 0001, "title": title, "ingredients": [A,B,C]}

Can I obtain my goal with any of the functions from apoc? Because I cannot find any (I assume they exist) method that allows to pick a JSON like the one above and create some nodes and relations between this nodes using the keys and values from the JSON itself. The desired graph would look like:

(Ingredient A) <----- [has] ---- (Recipe) ---- [has] ----> (Ingredient B)

Can Neo4j achieve this somehow?

Thank you for reading.

1 ACCEPTED SOLUTION

apoc.load.json

...is probably one of the most used procedures in APOC. I'm using it a lot in my own project. Here's one of my cypher scripts combining periodic.commit with load.json, to handle large volumes of data.

Here's a short example, using a valid tweak of your json:

Source data at url: https://example.com/data/bakery.json

{
    "documents" :  [
        {"id": 1001, "title": "Cake", "ingredients": ["flour","eggs","sugar"]},
        {"id": 1002, "title": "Cookie", "ingredients": ["flour","eggs","sugar","chocolate"]}
    ]
}

Cypher

CALL apoc.load.json("https://example.com/data/bakery.json") YIELD value
UNWIND value.documents AS doc
  MERGE (d:Document {id: doc.id})
  SET d.title = doc.title

  UNWIND doc.ingredients as ingredient
    MERGE (i:Ingredient {name: ingredient})
    MERGE (d)-[:USES]->(i)

I'd advise putting ingredient quantities in the :USES relationship once you have them:

...
MERGE (d)-[u:Uses]->(i)
  SET u.unit = "cup"
  SET u.amount = "1.5"
  SET u.readable = "1 1/2 cups"
  SET u.ml = 350

Recipes come with many other complex patterns, like ordered steps, time/temp, methods. Those will get fun and interesting very quickly, if you're going to dive that deep. You could also, just as easily, stick the steps and explanation as text on the :Document node, and not worry about graphing it at all.

View solution in original post

1 REPLY 1

apoc.load.json

...is probably one of the most used procedures in APOC. I'm using it a lot in my own project. Here's one of my cypher scripts combining periodic.commit with load.json, to handle large volumes of data.

Here's a short example, using a valid tweak of your json:

Source data at url: https://example.com/data/bakery.json

{
    "documents" :  [
        {"id": 1001, "title": "Cake", "ingredients": ["flour","eggs","sugar"]},
        {"id": 1002, "title": "Cookie", "ingredients": ["flour","eggs","sugar","chocolate"]}
    ]
}

Cypher

CALL apoc.load.json("https://example.com/data/bakery.json") YIELD value
UNWIND value.documents AS doc
  MERGE (d:Document {id: doc.id})
  SET d.title = doc.title

  UNWIND doc.ingredients as ingredient
    MERGE (i:Ingredient {name: ingredient})
    MERGE (d)-[:USES]->(i)

I'd advise putting ingredient quantities in the :USES relationship once you have them:

...
MERGE (d)-[u:Uses]->(i)
  SET u.unit = "cup"
  SET u.amount = "1.5"
  SET u.readable = "1 1/2 cups"
  SET u.ml = 350

Recipes come with many other complex patterns, like ordered steps, time/temp, methods. Those will get fun and interesting very quickly, if you're going to dive that deep. You could also, just as easily, stick the steps and explanation as text on the :Document node, and not worry about graphing it at all.

Nodes 2022
Nodes
NODES 2022, Neo4j Online Education Summit

On November 16 and 17 for 24 hours across all timezones, you’ll learn about best practices for beginners and experts alike.