unltd_J
unltd_J

Reputation: 494

mongoDB updating values to sum and record when record already exists in collection

I'm struggling wrapping my head around how to do this, but hopefully I can get some help here.

I have a collection in MongoDB that has values aggregated over a day. I have an index in the collection that enforces each record to be unique (name, date).

Because of issues I don't control, there is occasionally data that is split in two when it should be one.

What I want to do is when an insert is attempted but fails because the unique condition would fail, I want to update the record with an aggregated value.

This is what I have so far...

update = db.collection.aggregate(
        [
            {
                "$addFields": {
                    "views": {"$sum": ["$views", "$views"]},
                    "avg_time": {"$avg": ["$avg_time", "$avg_time"]}
                }
            },
            {
                "$out": {"db": "collection"}
            }
        ]
    )

I think where i'm confused is, I don't see how mongoDB knows which record I'm attempting to update and how I refer to the old value in the query just can't be correct.

Upvotes: 0

Views: 402

Answers (1)

hhharsha36
hhharsha36

Reputation: 3349

You should replace the $out Pipeline with the $merge Pipeline with whenMatched option set based on your requirement.

update = db.collection.aggregate([
  {
    "$addFields": {
      "views": {
        "$sum": [
          "$views",
          "$views"
        ]
      },
      "avg_time": {
        "$avg": [
          "$avg_time",
          "$avg_time"
        ]
      }
    }
  },
  {
    "$merge": {
      into: "collectionName",  // Collection name you want to merge with
      on: "_id",  // The unique indexed key name which is creating the conflict
      whenMatched: "keepExisting",  // Action to perform when the reference key already exists
      whenNotMatched: "insert"  // Action to perform when there are no conflicts
    }
  }
])

Refer to the MongoDB $merge pipeline documentation for more info on various match options available

Upvotes: 1

Related Questions