Mongodb 维护具有前3个元素的嵌入式阵列

Mongodb 维护具有前3个元素的嵌入式阵列,mongodb,mongodb-query,Mongodb,Mongodb Query,我目前正在开发一款手机赛车游戏 用户完成曲目后,将向“播放”集合添加一个新文档 此外,如果用户及时完成第三/第二/第一轨道。用户id和时间将添加到此曲目的“最佳”数组中。(新的第四名用户将从阵列中删除) 由于2个以上的用户可以同时完成一首曲目,我可能需要将其设置为原子级。所以我用findAndModify 到目前为止,如果我只保持在阵列中的第一位,我就能够做得很好。这就是我所做的: db.collection('tracks').findAndModify( { $or: [ {_id:

我目前正在开发一款手机赛车游戏

用户完成曲目后,将向“播放”集合添加一个新文档

此外,如果用户及时完成第三/第二/第一轨道。用户id和时间将添加到此曲目的“最佳”数组中。(新的第四名用户将从阵列中删除)

由于2个以上的用户可以同时完成一首曲目,我可能需要将其设置为原子级。所以我用findAndModify

到目前为止,如果我只保持在阵列中的第一位,我就能够做得很好。这就是我所做的:

db.collection('tracks').findAndModify(
    { $or: [ {_id: track_id, 'best': {$exists: false}}, {_id: track_id,'best.0.time': {$gt: _time}} ] },
    [],
    {$set : {'best.0' : {'user_id': _userId, 'time': _time} }},
    (err, data) => {
      if (err) return app_res.send(err);

      app_res.send (data.value != null);
      }
    );
但我的目标是保持3个最好的。 我在MongoDB文档中查看了数组操作符,但我不明白它们是如何(如果)帮助我实现目标的

还有什么我能做的吗

编辑:为了更清楚地说明这一点,前三名表示前三名用户及其热门时间。例如,如果“最佳”数组为:

1. user: a, time : 5.
2. user: b, time : 9.
3. user: c, time : 20.
然后,用户c在7秒内完成该曲目,然后“最佳”更改为:

1. user: a, time : 5.
2. user: c, time : 7.
3. user: b, time : 9.

我的模式:

用户:

{
  "_id": {
    "$oid": "123"
  },
  "name": "A name"
}
轨道:

{
  "_id": {
    "$oid": "765"
  },
  "name": "A track name",
  "length": 34.65,
  "best": [{"user_id": 467,"time": 24},{"user_id": 532,"time": 47},{"user_id": 953,"time": 89}]
}
播放:

{
  "_id": {
    "$oid": "1"
  },
  "time": 300000,
  "date": {
    "$date": "2018-08-15T14:05:47.872Z"
  },
  "user_id": {
    "$oid": "123"
  },
  "track_id": {
    "$oid": "765"
  }
}

以下是您如何做到这一点的-使用一些特殊的,可用于:


成功了!谢谢有没有办法保持前三名的用户id不同?因为我想保持前三名用户的最高记录时间。(而不是前三名)谢谢我不认为使用简单的MongoDB服务器端代码是可能的,至少只要这个JIRA还没有解决:也就是说(而且不知道你的具体游戏),我个人对高分的期望是,如果我三次打破它,我将获得第一、第二和第三名。。。如果我的成功仅仅因为我已经进入高分而被忽略,我会觉得自己被低估了,但我实际上更快了……这不会被忽略,目标是保持3名最佳球员和他们的最佳高分,所以如果你打破记录,它会被更新。如果你也被一名玩家击败,你的进入将在阵法中推到他前面。
db.tracks.update({}, {
    $push: {
        "best": {
            $each: [ {"user_id": 123,"time": 1} ], // add a new item to the "best" array
            $slice: 3, // keep only top three
            $sort: { "time": 1 } // rank/sort based on "time" field
        }
    }
})