Search code examples
jsonrethinkdbrethinkdb-python

How do I delete/update from nested document array


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.


Solution

  • 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"])});