Julian Mann Julian Mann - 13 days ago 5
Javascript Question

equivalent of capture group for matched subdocument

I have a Chats collection with a participants subdocument like so..

{
_id: '1',
participants: [ { _id: 'A', seen: false }, { _id: 'B', seen: false } ],
messages: []
}


There are only 2 participants and one of them is the currentUser. I don't know which. Also, there is only ever one chat for any pair of users.

In order to find a chat I use both user ids. So a find query looks like this:

Chats.find(
{ $and: [
{ participants: {$elemMatch: {_id: otherUserId}}},
{ participants: {$elemMatch: {_id: currentUserId}}}
]}
)


I'd like to allow the currentUser to update his own
seen
field in one update operation.

Currently I have to find the chat first, determine which index of the two users is the currentUser, then build a document to update that user and update it in a separate operation.

Is there something similar to a regex capture group so I can know the id of the element that matched currentUserId? Possibly like this.....

Chats.update( { $and: [
{ participants: {$elemMatch: {_id: otherUserId}}},
{ participants: capture({$elemMatch: {_id: currentUserId}})}
]},
{
$set: {"participants.(capture[0]).seen": true}
})


Or is there a better way?

Answer

Well this may not be a solution you're looking for but I thought I should suggest in case it helps.

Chats.update(   {   $and: [ 
    { participants: {$elemMatch: {_id: otherUserId}}}, 
    { participants: {$elemMatch: {_id: currentUserId}}} 
]},  
{   
    $set: {"participants.$.seen": true}
})

This will work for you because the $elemMatch stores the index of the matched array. As your anding the $eleMatch, it will store the index matched by the last $eleMatch which will be current user in your case. So, when you use the positional opertor, it will update the seen field for current user.