Home > Blockchain >  MongoTemplate upsert property snapshot
MongoTemplate upsert property snapshot

Time:11-21

I'm using mongo 4.2.15

Here is entry:

{
  "keys": {
    "country": "US",
    "channel": "c999"
  },
  "counters": {
    "sale": 0
  },
  "increments": null
}

I want to be able to initialize counter set as well as increment counters.sale value and save increment result snapshot to increments property. Something like that:

db.getCollection('counterSets').update(
{ "$and" : [
    { "keys.country" : "US"}, 
    { "keys.channel" : "c999"}
  ]
},
{ "$inc" : 
    { "counters.sale" : 10
    },
  "$set" : 
    { "keys" : 
        { "country" : "US", "channel" : "c999"}, 
      "increments":
        { "3000c058-b8a7-4cff-915b-4979ef9a6ed9": {"counters" : "$counters"} }
    }
},
{upsert: true})

The result is:

{
    "_id" : ObjectId("61965aba1501d6eb40588ba0"),
    "keys" : {
        "country" : "US",
        "channel" : "c999"
    },
    "counters" : {
        "sale" : 10.0
    },
    "increments" : {
        "3000c058-b8a7-4cff-915b-4979ef9a6ed9" : {
            "counters" : "$counters"
        }
    }
}

Does it possible to do such update which is some how copy increment result from root object counters to child increments.3000c058-b8a7-4cff-915b-4979ef9a6ed9.counters with a single upsert. I want to implement safe inrement. Maybe you can suggest some another design?

CodePudding user response:

In order to use expressions, your $set should be part of aggregation pipeline. So your query should look like

NOTE: I've added square brackets to the update

db.getCollection('counterSets').update(
{ "$and" : [
    { "keys.country" : "US"}, 
    { "keys.channel" : "c999"}
  ]
},
[ {"$set": {"counters.sale": {"$sum":["$counters.sale", 10]}}}, {"$set": {"increments.x": "$counters"}}],
{upsert: true})

I haven't found any information about the atomicity of aggregation pipelines, so use this carefully.

  • Related