问题
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
- For the player making the kill
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