2

Given a document as below how can I delete or update from the nested document ingredients ? Any help, I am new to this rethinkdb. The table stores this documents called recipes.

[
    {
        "cook": "9 min",
        "id": "be63fc32-c1b5-4c67-a967-b6868f095216",
        "inactive": "20 min",
        "ingredients": [
            "2 cups fresh parsley leaves, chopped",
            "8 large sprigs fresh thyme, chopped",
            "4 large sprigs fresh rosemary, chopped",
            "3 cloves garlic, minced",
            "1 small shallot, diced",
            "2 tablespoons cracked black peppercorns",
            "2 tablespoons cracked pink peppercorns",
            "1 1/4 cups extra-virgin olive oil",
            "8 skin-on chicken thighs",
            "Flaky salt, such as Maldon, for seasoning",
            "Salad, for serving"
        ],
        "level": "Easy",
        "prep": "5 min",
        "title": "Asian Grilled Salmon",
        "total": "34 min",
        "yields": "6 servings"
    },
    ....

I tried as you see below, and it worked. But I want to know if there is a better way.

class Ingredients:
    def __init__(self, name):
        self.name = name

    @classmethod
    def update(self, recipe, name, position):
        __db__ = recipe.__class__.__db__()
        __table__ = recipe.__class__.__table__()
        result = (
            __table__.get(recipe.id)
            .update(
                {
                    "ingredients": __db__.r.row["ingredients"].change_at(
                        position, name
                    )
                }
            )
            .run(__db__.conn)
        )

        return recipe.ingredients

    @classmethod
    def destroy(self, recipe, recipe_name):
        __db__ = recipe.__class__.__db__()
        __table__ = recipe.__class__.__table__()
        __table__.get(recipe.id).update(
            {
                "ingredients": __db__.r.row["ingredients"].filter(
                    lambda name: name != recipe_name
                )
            }
        ).run(__db__.conn)

        return recipe.ingredients

Ingredients class is an attempt to model the ingredients: [..] part of the parent document in Python.

Arup Rakshit
  • 109,389
  • 25
  • 234
  • 293

1 Answers1

2

For updating you can iterate over the ingredients with map, find the one that you want to update and change its value:

r.db("test").table("sample").get("be63fc32-c1b5-4c67-a967-b6868f095216")
   .update({
     ingredients: r.row("ingredients").map(function(sub){  
       return r.branch(sub.eq("2 cups fresh parsley leaves, chopped"),
         "2 cups fresh baby poo, marinated", sub)
     })
   })  

For deleting you can use the difference function:

r.db('test').table('sample').get('be63fc32-c1b5-4c67-a967-b6868f095216')
  .update({ingredients: r.row('ingredients')
    .difference(["4 large sprigs fresh rosemary, chopped"])});  
taygetos
  • 2,644
  • 2
  • 15
  • 24
  • thanks for your answer. I will try them. What is `sub` doing here? Also what other active help sties are there where I can ask questions related to rethinkdb? – Arup Rakshit Jun 17 '19 at 10:55
  • "sub" is just a variable, stands for one element in the array of ingredients. I don't know any active q&a sites for rethinkdb – taygetos Jun 17 '19 at 11:01
  • Thanks. I found a solution after I posted this answer, so I added it to the main post. I think in case of destroy `difference` is much better than what I had tried. thanks for your time. – Arup Rakshit Jun 17 '19 at 18:24
  • Ohh right, if you know the position then using the ´changeAt` is better ;) . – taygetos Jun 17 '19 at 18:34