I have a game
collection that looks like this:
[
{
_id: ObjectId("6314dc4de4ad4c8141ce0b08"),
status: "started",
channel: "myChannel",
teams: [
{
name: "myFirstTeam",
score: 0,
users: [
{
id: 9082376,
name: "myFirstUser"
},
{
id: 289168,
name: "mySecondUser"
},
]
},
{
name: "mySecondTeam",
score: 0,
users: [
{
id: 898323,
name: "myThirdUser"
}
]
}
]
}
]
I managed to add a user to a team of a specific size:
db.collection.update({
"channel": "myChannel",
"teams.users": {
$size: 1
}
},
{
$push: {
"teams.$.users": {
id: 23424234,
name: "myUserName"
}
}
})
My goal is to add a user to a specific game on the smallest team. I'm new with mongodb
, I don't even know if that's possible with a request only. I see the $min and $count but I can't find how to use it.
You can try on this playground
BONUS: Check to make sure the userId added is not already on any team of this game, inside the query (but I can check that before or/and after)
CodePudding user response:
Query
- update pipeline, because you need more complicated update
- it could be smaller with more queries but this does all with 1 query
- find the number of members of the smallest team for example size=1
- reduce the teams, with initial value
{found false new-teams []}
if we are in the team with the smallest size, we add the new member, and turn found to true, else we just add the team as it is
*i didn't added way to check if user exists, its not hard to add it, but i didnt know what to do if it existed and what to do if didnt exist, query is big and you are new, dont know if it will help you, i cant think now of smaller way to do it with 1 query
updateOne(
{"channel": {"$eq": "myChannel"}},
[{"$set": {"new-member": {"id": 23424234, "name": "myUserName"}}},
{"$set":
{"min-size":
{"$min":
{"$map":
{"input": "$teams", "as": "t", "in": {"$size": "$$t.users"}}}}}},
{"$set":
{"teams":
{"$reduce":
{"input": "$teams",
"initialValue": {"added": false, "new-teams": []},
"in":
{"$let":
{"vars": {"v": "$$value", "t": "$$this"},
"in":
{"$cond":
[{"$or":
["$$v.added", {"$gt":
[{"$size": "$$t.users"}, "$min-size"]}]},
{"added": "$$v.added",
"new-teams": {"$concatArrays": ["$$v.new-teams", ["$$t"]]}},
{"added": true,
"new-teams":
{"$concatArrays":
["$$v.new-teams",
[{"$mergeObjects":
["$$t",
{"users":
{"$concatArrays":
["$$t.users", ["$new-member"]]}}]}]]}}]}}}}}}},
{"$set":
{"teams": {"$getField": {"field": "new-teams", "input": "$teams"}}}},
{"$unset": ["new-member", "min-size"]}])