0

If I have a structure like this in the document

...
updatedAt: 2021-01-17T16:44:28.824+00:00
vid: (Array)
  0: (Array)
    0: "adfsdfasfd"
    1: "this is some sample text"
    2: "https://example.com"
  1: (Array)
    0: "gfjghjhjgh"
    1: "this is another sample text"
    2: "https://example2.com"
...

how do I update for instance the array vid[0][0] knowing "adfsdfasfd" ?

in order to get the whole vid[0][0] array I'm using this:

const foundVid = await db.collection('users').find({vid: {$elemMatch: {$elemMatch: {$in: ["adfsdfasfd"]}}}}).project({"vid.$": 1, "_id": 0 }).toArray()

which console.log(foundVid):

{ 
  vid: [
         [
           "adfsdfasfd"
           "this is some sample text"
           "https://example.com"
         ]
       ]
}

then I tried both $set and $addToSet like:

let update = {
    vid: [
        [foundVid[0].vid[0][0], foundVid[0].vid[0][1], foundVid[0].vid[0][2], views, likes, date]
    ]
}

await db.collection('users').updateOne(
 {
   vid: {
     $elemMatch: {
       $elemMatch: {
         $in: [
           "adfsdfasfd"
         ]
       }
     }
   }
 },
 { $addToSet : update }
)

but it doesn't seem to work..

EDIT: what I'm trying to accomplish is to update one array elements by knowing it's first string (which is an id), so after updating my vid[0][0] as described above it should look like:

...
updatedAt: 2021-01-17T16:44:28.824+00:00
vid: (Array)
  0: (Array)
    0: "adfsdfasfd"
    1: "this is some sample text"
    2: "https://example.com"
    3: 1000
    4: 100
    5: <a date here>
  1: (Array)
    0: "gfjghjhjgh"
    1: "this is another sample text"
    2: "https://example2.com"
...

EDIT 2: I'm sorry I thought was implicit with the term "update" instead of changing the array, I'd need to update it as if it was a $set. This is why I went towards recreating the array (let update = ...) with the first three current values + updated variables views, likes, date.

The problem with $set is that it appears to update the whole vid array with only this array in it resulting in:

...
updatedAt: 2021-01-17T16:44:28.824+00:00
vid: [
   0: [
     0: "adfsdfasfd"
     1: "this is some sample text"
     2: "https://example.com"
     3: 1000
     4: 100
     5: <a date here>
   ]
]
...
2
  • Can you show what result you're trying to get to? What should your original document look like after the update? Commented Jan 27, 2021 at 0:19
  • Updated with what i'm trying to achieve in better details Commented Jan 27, 2021 at 13:41

1 Answer 1

2

It does seem like you're pretty close here. As you point out, to match that value in the array of arrays, you would run this query:

db.collection.find({
  "vid": {
    $elemMatch: {
      $elemMatch: {
        $in: [
          "adfsdfasfd"
        ]
      }
    }
  }
})

But to update it, you would need:

db.collection.update({
  "vid": {
    $elemMatch: {
      $elemMatch: {
        $in: [
          "adfsdfasfd"
        ]
      }
    }
  }
},
{
  "$push": {
    "vid.$": {
      $each: [
        1000,
        100,
        new Date()
      ]
    }
  }
})

The key here is the positional $ operator.

Playground

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

8 Comments

vid is an array of arrays, not the direct array which contains "adfsdfasfd" thought, please check my similar thread with screenshot from mongodb stackoverflow.com/questions/65763620/…
@m4tt I see. Will take a look in a second. Thanks for pointing it out.
@m4tt Updated the answer.
@m4tt Nope, $push will blindly push anything you want into the matched array. In order to check that you will need to adjust your match query to not even select arrays that contain those variables. So the $elemMatch will need something like $nin:['xxx'] added to it.
@m4tt I that case, I would not use an array to store that date. It needs to be an object like {name: 'adfsdfasfd', likes: 1000, date: Date, etc.}. Otherwise it's gonna be a nightmare for you to update that stuff.
|

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.