Shri
Shri

Reputation: 752

MongoDB find matching document and update matching field inside array of objects

So I have this document structure for a threads object where each thread contains multiple messages and also contains the data of which user has read upto which message:

Threads collection:

{
    _id: ObjectId("5f1f0725850eca800c70ef9e"),
    thread_participants: [
      ObjectId("5f1efeece50f2b25d4be2de2"),
      ObjectId("5f1eff1ae50f2b25d4be2de4"),
    ],
    messages: [
      {
        id: ObjectId("5f1f0725850eca800c70ef98"),
        content: "Hello",
      },
      {
        id: ObjectId("5f1f0725850eca800c70ef92"),
        content: "Hey there!",
      },
    ],
    seen_status: [
        {
            user_id: "5f1efeece50f2b25d4be2de2",
            last_read_message_id: ObjectId("5f1f0725850eca800c70ef98")
        },
        {
            user_id: "5f1eff1ae50f2b25d4be2de4",
            last_read_message_id: null //User has not opened the conversation at all.
        }
    ],
    date_created: ISODate("2020-07-27T16:29:54.702Z"),
}
...
...
...
multiple threads

How do I update last_read_message_id of a specific user_id on thread 5f1f0725850eca800c70ef9e, for user_id 5f1eff1ae50f2b25d4be2de4?

Upvotes: 1

Views: 33

Answers (2)

Kunal Mukherjee
Kunal Mukherjee

Reputation: 5853

Update the inner document using arrayfilters and positional operator $.

Note - This requires MongoDb 3.6+

var filter = {
    _id: ObjectId('5f1f0725850eca800c70ef9e')
};

var update = {
    $set: {
        'seen_status.$[item].last_read_message_id': 5
    }
};

var options = {
    arrayFilters: [
        {
            'item.user_id' : ObjectId('5f1eff1ae50f2b25d4be2de4')
        }
    ]
};
db.collection.update(filter, update, options);

Upvotes: 1

mickl
mickl

Reputation: 49945

You can use the $ positional operator:

db.col.update({ _id: ObjectId("5f1f0725850eca800c70ef9e"), seen_status.user_id: "5f1eff1ae50f2b25d4be2de4" }, { $set: { 'seen_status.$.last_read_message_id': newValue } }

Upvotes: 1

Related Questions