MongoDB 4.2 update pipeline: “Push or Update” in nested array

The update query:

db.exp.update( { BlogId: 1 },
  [ 
      { 
          $set: { 
              Items: {
                  $reduce: {
                      input: { $ifNull: [ "$Items", [] ] }, 
                      initialValue: { items: [], update: false },
                      in: {
                          $cond: [ { $eq: [ "$$this.Cat", INPUT_DOC.Cat ] },
                                   { 
                                     items: { 
                                        $concatArrays: [
                                            "$$value.items",
                                            [ { Cat: "$$this.Cat", Up: { $add: [ "$$this.Up", 1 ] } } ],
                                        ] 
                                      }, 
                                      update: true
                                   },
                                   { 
                                      items: { 
                                         $concatArrays: [ "$$value.items", [ "$$this" ] ] 
                                      }, 
                                      update: "$$value.update" 
                                   }
                          ]
                      }
                  }
              }
          }
      },
      { 
          $set: { 
              Items: { 
                  $cond: [ { $eq: [ "$Items.update", false ] },
                           { $concatArrays: [ "$Items.items", [ INPUT_DOC ] ] },
                           { $concatArrays: [ "$Items.items", [] ] }
                  ] 
              }
          }
      }
  ] 
)

The update does the following:

  • if the Cat exists increments the Up value by 1
  • if the Cat not exists adds the INPUT_DOC to the Items array
  • If the Items array doesn’t exist, creates the array and adds the INPUT_DOC

Try with the object values: INPUT_DOC = { Cat: 1, Up: 555 }, or INPUT_DOC = { Cat: 3, Up: 888 }

1 Like