这里想到的一件事是您可能不需要做所有您认为需要做的工作,并且您的问题可能会在TTL 索引和可能有上限的集合的帮助下得到解决。考虑以下条目:
{ "_id" : ObjectId("531cf5f3ba53b9dd07756bb7"), "user" : "A", "units" : 50 }
{ "_id" : ObjectId("531cf622ba53b9dd07756bb9"), "user" : "B", "units" : 62 }
所以有两个条目,_id
当你插入时你得到了那个值。所以一开始,“A”没有人可以对抗,但“B”的条目将与之前的人对抗。
ObejctId 是单调的,这意味着“下一个”总是比上一个值更大。因此,使用插入的数据,只需执行以下操作:
db.moves.find({
_id: {$lt: ObjectId("531cf622ba53b9dd07756bb9") },
user: { $ne: "B" }
}).limit(1)
这将前面插入的“移动”赋予刚刚进行的当前移动,并且这样做是因为先前插入的任何东西都将具有_id
比当前项目更小的值。您还要确保您没有“玩”用户自己的举动,当然您将结果限制在一个文档中。
所以“移动”将永远向前,当用户“C”进行下一次插入时,他们从用户“B”那里获得“移动”,然后用户“A”将从用户“C”那里获得“移动” “, 等等。
这里“可能”发生的所有事情都是“B”按顺序进行下一个“移动”,并且您将拾取与上一个请求中相同的文档。但这是你的“会话”设计的重点,存储最后的“结果”并确保你没有得到同样的东西,因此,在你的设计中处理你想要的任何东西。
这应该足以“玩”。但是,让我们进入您的“删除”部分。
自然你“认为”你想删除东西,但回到我最初的“帮手”,这应该是没有必要的。从上面看,删除只是“清理”的一个因素,所以你的收藏不会增长到很大的比例。
如果你应用了一个 TTL 索引,就像本教程解释的那样,你的集合条目将被清理,并在一段时间后被删除。
还有什么可以做的,特别是考虑到我们正在使用密钥的增加性质_id
并且这或多或少是一个“队列”本质上,你可以将它应用为一个上限集合。因此,您可以将最大尺寸设置为在任何给定时间将保留多少“移动” 。
将这两者结合在一起,你会得到一些只会“增长”到一定大小的东西,并且会自动为你清理,如果活动慢一点的话。这将使所有操作保持快速。
底线是,您担心的“删除”并发性已通过实际“删除”删除刚刚播放的文档的需要而被删除。查询保持简单,TTL 索引和上限集合为您管理数据。
所以你有我对一个非常并发的“盲战”游戏的看法。