0

I have the following documents:

{
  _id: ObjectId('111111111111111111114444'),
  books: [
    {
      id: ObjectId('111111111111111111113333'),
      pictures: []
    },
    {
      id: ObjectId('111111111111111111112222'),
      pictures: []
    }
  ],
  // others attributes
}

What I need to do is to add an element to pictures. Keep in mind that I have the documentId which is the id of the document, and the bookId which is the Id of an element of books.

If I want to add the element {description: "nice picture"} to the document 111111111111111111114444 in the book 111111111111111111113333, the updated document would look like

{
  _id: ObjectId('111111111111111111114444'),
  books: [
    {
      id: ObjectId('111111111111111111113333'),
      pictures: [
        {
          description: "nice picture"
        }
      ]
    },
    {
      id: ObjectId('111111111111111111112222'),
      pictures: []
    }
  ],
  // others attributes
}
2
  • Just to be clear, your Books collection has an _id? Commented Nov 4, 2021 at 12:54
  • The books is an array of objects, which yes, they have an id Commented Nov 4, 2021 at 12:59

1 Answer 1

1

Query

  • pipeline update requires MongoDB >= 4.2
  • filter the "_id"
  • map on books if id=2 merge objects, with the pictures containing the new element
  • else if not id=2 dont change the book

*i used 1,2,3 for ids (its the same code)

PlayMongo

update({"_id" : 1},
[{"$set": 
   {"books": 
     {"$map": 
       {"input": "$books",
        "in": 
        {"$cond": 
          [{"$eq": ["$$book.id", 2]},
           {"$mergeObjects": 
             ["$$book",
               {"pictures": 
                 {"$concatArrays": 
                   ["$$book.pictures", [{"description": "nice picture"}]]}}]},
           "$$book"]},
        "as": "book"}}}}])

Edit

Query

  • if pictures isnt't array(or dont exists), creates an empty array

PlayMongo

update({"_id" : 1},
[{"$set": 
    {"books": 
      {"$map": 
        {"input": "$books",
          "in": 
          {"$cond": 
            [{"$eq": ["$$book.id", 2]},
              {"$mergeObjects": 
                ["$$book",
                  {"pictures": 
                    {"$concatArrays": 
                      [{"$cond": 
                          [{"$isArray": ["$$book.pictures"]}, "$$book.pictures",
                            []]},
                        [{"description": "nice picture"}]]}}]},
              "$$book"]},
          "as": "book"}}}}])
Sign up to request clarification or add additional context in comments.

4 Comments

what if there is not an array yet? It would make concatArrays of null and another array which probably will turn out as null. We can't make $concatArrays of undefined. How can I solve this? I tried with $push but for some reason it doesn't accept it..
i updated for that case but if you have special cases of schema, ask about them in the question, because answer is based on the schema you sended that pictures was array always.
I apologize for my mistake. Thank you
no worries its mostly for you to get better answers

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.