1

So, this question stems from another question I asked ( MongoDB update with conditional addToSet/pull )

Essentially in that SO question, I found that I couldn't use the typical $in syntax if my array is an array of objects.

Typical syntax for conditionally updating a field:

$cond: {
    $in: [{element}, $arr],  // Need to provide the element Exactly, including _id if one exists
    $setDifference: [$arr, [{element}]]
    $concactArrays: [$arr, [{element}]]
}

The reason $in doesn't work is that if _id is auto-generated, you won't be able to match it for the $in or the $setDifference. The solution I arrived at uses $filter, but is fragile in that the array needs to at least be initialed a default [] (otherwise $size will error out on a null array)

On to my question. Is there a way to make $in or $elemMatch work in this scenario? I couldn't get the following to work (says $elemMatch is an unrecognized expression:

$cond: {
    $in: [arr: {$elemMatch: {element}}, $arr],

Full Example
Mongo Object

{_id: 1, message: 'text1'}
{_id: 2, message: 'text2', reactions: [{_id: autoGen1, user: 'bob', reaction:''},
                                       {_id: autoGen2, user: 'bob', reaction:''}
                                       {_id: autoGen3, user: 'meg', reaction:''}]}

Update Query

db.collection.update(
{},
[
  {
    $set: {
      reactions: {
        $cond: [
          {
            $in: [
               {
                  reactions: { $elemMatch: {user: "bob", reaction: "good"}} 
               },
               "$reactions"
            ]
          },
          "1",
          "2"
        ]
      }
    }
  }
])

https://mongoplayground.net/p/Ig0TKMAMNkI

Gabriel Lupu
  • 1,397
  • 1
  • 13
  • 29
SimpleMind
  • 29
  • 7
  • Have you considered `$ifNull` or `$type` to make sure the value is an array before `$filter`? – Joe Jun 22 '21 at 06:11

0 Answers0