【问题标题】:MongoTemplate upsert property snapshotMongoTemplate upsert 属性快照
【发布时间】:2021-12-29 10:11:31
【问题描述】:

我正在使用 mongo 4.2.15

这里是条目:

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

我希望能够初始化计数器集以及递增counters.sale 值并将递增结果快照保存到increments 属性。类似的东西:

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})

结果是:

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

是否可以进行这样的更新,这是如何通过单个 upsert 从根对象 counters 复制增量结果到子 increments.3000c058-b8a7-4cff-915b-4979ef9a6ed9.counters 的。我想实施安全措施。或许你可以推荐一些其他的设计?

【问题讨论】:

  • 您是否尝试明确设置每个计数器? "counters.sale": "$counters.sale"
  • @geobreze 结果是"increments" : { "3000c058-b8a7-4cff-915b-4979ef9a6ed9" : { "counters.sale" : "$counters.sale" } }

标签: java mongodb mongodb-query upsert mongotemplate


【解决方案1】:

为了使用表达式,您的$set 应该是聚合管道的一部分。所以你的查询应该是这样的

注意:我在更新中添加了方括号

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

我没有找到任何关于聚合管道原子性的信息,所以请谨慎使用。

【讨论】:

  • 感谢您的回复。这对我行得通。这个请求应该在多线程中执行。我将创建一个测试来验证原子性并报告它是否是线程安全的。
  • 好吧,解决方案本身是线程安全的,但性能不是很好。在具有 100 个线程的同一计数器集上的空数据库 1000 次增量花费了 118 秒。
猜你喜欢
  • 2016-11-05
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-25
  • 1970-01-01
相关资源
最近更新 更多