Как создать, обновить или добавить вложенный документ

Я новичок в rethinkdb и работаю над инструментом администрирования для игрового сервера, в котором мне нужно записывать убийства и смерти игроков. У меня есть следующая структура для игрока, в котором "имя" является вторичным индексом:

"name": NameofPlayer,
"sessions:" [
    {
        "id": IDofSession,
        "kills": NumberofKills,
        "deaths": NumberofDeaths,
        "hskr": HSKR%,
        "weapons": [
            {
                "name": WeaponName,
                "kills": NumberofKills,
                "headshots": NumberofHeadshots
            },
        ] 
   },
]

Я получаю текущий идентификатор сеанса с сервера, и при убийстве срабатывает событие, которое возвращает убийцу, жертву, имя оружия и выстрел в голову (истина/ложь). Мне нужно создать обновление для обоих игроков, связанных со следующим:

  • Если сеанс игрока с текущим id с сервера не существует, создайте его
  • If a session exists with the current id then
    • For the player making the kill
      • Update the number of total kills, and headshot-kill ratio
      • Если оружия не существует, создайте его и запишите имя, убийства и выстрелы в голову.
      • Если оружие существует, обновите количество убийств и выстрелов в голову.
    • For player being killed
      • Update number of total deaths

Мне нужно сохранить указанную выше структуру игроков, но я готов обновить игроков.


person Austin Catcher    schedule 28.04.2016    source источник
comment
Эй, Остин, ты нашел решение этой проблемы?   -  person dalanmiller    schedule 03.08.2016


Ответы (1)


Что-то похожее на это будет делать свое дело:

const sessionId = 123; 
const players = r.db("game").table("players");

r.branch(
  // Check if session in player `sessions` array
  players.get(playerId)('sessions').map((session) => {return session.id}).coerceTo('array').contains(sessionId),
 // 
  players.get(playerId).update({
    'sessions': r.row('sessions').append({
      'id': newSessionId,
      // Set rest of initial values here
    })
  }),

// Else don't need to do anything
'_'
// Now we insert the kill
).do((_) => {

  var original_session = players.get(playerId)('sessions').filter(r.row('id').eq(sessionId));
  var original_session_index = players.get(playerId)('sessions').offsetsOf(r.row('id').eq(sessionId);

  players.get(playerId).update({
    'sessions': r.row('sessions').changeAt(
      // First get index
      original_index,
      // Then create replacement object
      original_session.merge({
     // New values go here which will overwrite previous ones.
     // e.g. update kills, deaths, weapons etc. 
       kills: original_session('kills').add(1),
       deaths: original_session('deaths').add(3)
      })
    )
  })
})

Вы можете видеть, что выполнение мутаций индексов во встроенном массиве довольно запутанно, поскольку вам нужно найти индекс элемента в массиве, а затем использовать .changeAt, чтобы заменить его модифицированным оригиналом.

Я бы рекомендовал либо дождаться окончания сеанса, чтобы обновить базу данных, либо просто сохранить все данные на стороне клиента или на стороне сервера, пока вам не нужно будет писать в базу данных. Или сохраните документы сеанса игрока в новой таблице, которую вы сможете быстрее найти и обновить. Соединение между таблицей игроков и таблицей сеансов будет простым и быстрым с помощью .eqJoin.

person dalanmiller    schedule 02.05.2016