Поддержка встроенного массива с тремя верхними элементами - PullRequest
0 голосов
/ 27 августа 2018

В настоящее время я работаю над мобильной гоночной игрой.

После того, как пользователь заканчивает дорожку, новый документ добавляется в коллекции «Воспроизведения».

Также, если пользователь заканчивает трек 3/2/1 по времени. идентификатор пользователя и время будут добавлены в «лучший» массив этого трека. (и новый пользователь 4-го места будет удален из массива).

Поскольку 2+ пользователи могут закончить трек в одно и то же время, мне, вероятно, нужно сделать это атомарным. поэтому я использовал findAndModify.

До сих пор мне удавалось делать это хорошо, если я поддерживаю только 1-ю позицию в массиве. вот что я сделал:

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 для операторов массива, но я не могу понять, как (и если) они не могут помочь мне достичь моей цели.

Есть ли в любом случае, я могу это сделать?

РЕДАКТИРОВАТЬ: Просто, чтобы сделать это более ясным, топ-3 показывает 3 лучших пользователей и их лучшие времена. например, если «лучший» массив:

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

1 Ответ

0 голосов
/ 27 августа 2018

Вот как это можно сделать - используя некоторые специальные модификаторы , которые можно использовать с $push:

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
        }
    }
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...