1

I have the following document:

{
  "_id" : ObjectId("5720bd01232ac527623f2889"),
  "planes" : [
      {
          "name" : "plane1",
          "wings" : [
              {
                  "name" : "rightDown"
              },
              {
                  "name" : "rightUp"
              }
          ]
      },
      {
          "name" : "plane2",
          "wings" : [
              {
                  "name" : "leftUp",
              },
              {
                  "name" : "leftDown",
              }
          ]
      }
  ]
}

I want to update an object in an array nested in an another array, without using the array index. In my example, 'plane2' with the property 'wing' named 'leftDown'. Is it possible ?

db.planes.update({
  planes: {
    $elemMatch: {
      wings: {
        $elemMatch: {
          name: 'leftUp'
        }
      }
    }
  }
}, 
// It would be wonderful if I the $set would look like this, 
// but the error is: 
// "Too many positional (i.e. '$') elements found in path 'planes.$.wings.$'"
//  
// It seems that $ holds only the value of the first nested 
// object in the array
{ 
  $set: {
    'planes.$.wings.$': {
        name: 'leftMagic'
    }
  }
})

MongoDb 3.2 documentation says: The positional $ operator cannot be used for queries which traverse more than one array, such as queries that traverse arrays nested within other arrays, because the replacement for the $ placeholder is a single value

But I'm still waiting for that miracle .. Are there any other clean/beautiful ways to do the update in a single shoot ?

1 Answer 1

1

Sadly no, the positional operator can only hold a single value. I don't think you can perform this update in a single shot with your current data structure.

You could perform one lookup to get the first array index, then a second with the positional operator, but at that point you could just traverse the array and resave the document.

With a little restructuring of your collections you could get the update down to a single operation. Check out MongooseJS populate.

Sign up to request clarification or add additional context in comments.

Comments

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.