How to create, update, or append a nested document

纵饮孤独 提交于 2019-12-13 06:13:54

问题


I am new to rethinkdb and I'm working on an admin tool for a game server in which I need to record player kills and deaths. I have the following structure for a player in which "name" is a secondary index:

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

I get the current session id from the server and an event fires on a kill that returns killer, victim, weapon name, and headshot(true/false). I need to create an update to both players involved with the following:

  • If a player session of the current id from the server does not exist, create one
  • 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
      • If a weapon does not exist create one and record name, kills, and headshot
      • If a weapon exists update number of kills and headshots
    • For player being killed
      • Update number of total deaths

I need to keep the above player structure but am open to how to update the players.


回答1:


Something similar to this will should do the trick:

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

You can see that doing mutations on indexes in an embedded array is quite convuluted as you have to find the index of the item in the array and then use the .changeAt operation to replace it with the modified original.

I would recommend either waiting until the end of the session to update the database and just keeping all the data client-side or server-side until you need to write to the db. Or, keep player-session documents in a new table which you can find more quickly and update more easily. Joining between your player table and your sessions table would be easy and quick with an .eqJoin.



来源:https://stackoverflow.com/questions/36926985/how-to-create-update-or-append-a-nested-document

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!