You have multiple nested array in your collections and in MongoDB you can't use multiple positional operator to perform update operation on your players collection. And you should define a name field and a role field for your players. You could structure your data like the following :
Team / Season document
{
"_id": ObjectId("58b99f08a7a2dfe1174e8eb9"),
"team": "Dragons",
"season": "2016-17",
"players": [{
"name": "Oliver queen",
"role": "pitcher"
}, {
"name": "SomeOne",
"role": "pitcher"
}, {
"name": "Slade Wilson",
"role": "catcher"
}]
}
So you will have one document per unique team/season pair, so :
- 1st document :
Dragons/2016-17
- 2nd document :
Dragons/2015-17
- etc...
Display a single player, based on their position (i.e 'pitcher'), for
a specific season for a specific team. For example I want to know who
the pitcher was for season 2015-16 for the dragons team.
_ If you have only one player by role use :
db.players.find({
"team": "Dragons",
"season": "2016-17",
"players.role": "pitcher"
}, { "players.$": 1 })
It will return only the first player matching the pitcher role :
{ "_id": ObjectId("58b99f08a7a2dfe1174e8eb9"), "players": [{ "name": "Oliver queen", "role": "pitcher" }] }
_ If you can have multiple player by role (like in the model above), use an aggregation to $filter the players array with the matching role :
db.players.aggregate([{
$match: {
"team": "Dragons",
"season": "2016-17",
"players.role": "pitcher"
}
}, {
$project: {
players: {
$filter: {
input: "$players",
as: "player",
cond: { $eq: ["$$player.role", "pitcher"] }
}
}
}
}])
That gives you :
{ "_id": ObjectId("58b99f08a7a2dfe1174e8eb9"), "players": [{ "name": "Oliver queen", "role": "pitcher" }, { "name": "SomeOne", "role": "pitcher" }] }
Display ALL players, based on their position, for all seasons for the
team Dragons.
Use an aggregation grouping by players.role :
db.players.aggregate([{
$match: {
"team": "Dragons"
}
}, {
$unwind: "$players"
}, {
$group: {
_id: "$players.role",
players: {
$push: "$players.name"
}
}
}])
That gives :
{ "_id": "catcher", "players": ["Slade Wilson", "Batman"] } { "_id": "pitcher", "players": ["Oliver queen", "SomeOne", "Joker"] }
Update the name for a specific player in a specific season for a
specific team. (Example, update "pitcher" in season 2016-17 for the
Dragons from "Oliver Queen" to "Green Arrow"
Update with positional parameter matching the item found :
db.players.update({
"team": "Dragons",
"season": "2016-17",
"players.name": "Oliver queen"
}, {
$set: {
"players.$.name": "Green Arrow"
}
});
Team / Season / Player document
{
"team": "Dragons",
"season": "2016-17",
"name": "Oliver queen",
"role": "pitcher"
}, {
"team": "Dragons",
"season": "2016-17",
"name": "SomeOne",
"role": "pitcher"
}, {
"team": "Dragons",
"season": "2016-17",
"name": "Slade Wilson",
"role": "catcher"
}
Each document features a player in a specific team, in a specific season
Display a single player, based on their position (i.e 'pitcher'), for
a specific season for a specific team. For example I want to know who
the pitcher was for season 2015-16 for the dragons team.
db.players.find({ "team": "Dragons", "season": "2016-17", "role": "pitcher" })
Display ALL players, based on their position, for all seasons for the
team Dragons.
db.players.find({"team": "Dragons", "role": "pitcher"})
Update the name for a specific player in a specific season for a
specific team. (Example, update "pitcher" in season 2016-17 for the
Dragons from "Oliver Queen" to "Green Arrow"
db.players.update({
"team": "Dragons",
"season": "2016-17",
"name": "Oliver queen"
}, {
$set: {
"name": "Green Arrow"
}
})