我是mongoDB场景的新手,我正在尝试找出返回底层对象的最佳方法,该对象位于对象数组中包含的对象中。我知道这听起来令人困惑,所以让我告诉你我在做什么。
{
"_id": ObjectId("58b833a04953db3dd302102b"),
"team": "Dragons",
"rosters": [{
"season": "2016-17",
"players": [{
"pitcher": "Oliver queen"
}, {
"catcher": "Slade Wilson"
}]
}, {
"season": "2015-16",
"players": [{
"pitcher": "Joker"
}, {
"catcher": "Batman"
}]
}]
}
所以我的最终目标是:
根据特定球队的特定赛季的位置(即“投手”)显示单个球员。例如,我想知道龙队的2015-16赛季投手是谁。
根据队伍的位置显示所有球员,为龙队提供所有赛季。
更新特定团队中特定团队的特定玩家的名称。 (例如,2016-17赛季“龙头队”从“奥利弗女王”到“绿箭”更新“投手”
这甚至是一个合理的查询构建?如果没有,我可以在哪里修复我的数据模型以提高性能?
提前致谢。
答案 0 :(得分:2)
您的集合中有多个嵌套数组,而在MongoDB中,您无法使用多个positional operator对您的播放器集合执行更新操作。您应该为玩家定义name
字段和role
字段。您可以按如下方式构建数据:
{
"_id": ObjectId("58b99f08a7a2dfe1174e8eb9"),
"team": "Dragons",
"season": "2016-17",
"players": [{
"name": "Oliver queen",
"role": "pitcher"
}, {
"name": "SomeOne",
"role": "pitcher"
}, {
"name": "Slade Wilson",
"role": "catcher"
}]
}
因此,每个独特的团队/季节对都会有一个文档,所以:
Dragons/2016-17
Dragons/2015-17
根据他们的位置(即'投手')显示单个玩家 特定团队的特定季节。例如,我想知道谁 投手是2015-16赛季的龙队。
_如果你只有一个角色使用的玩家:
db.players.find({
"team": "Dragons",
"season": "2016-17",
"players.role": "pitcher"
}, { "players.$": 1 })
它只返回匹配pitcher
角色的第一个玩家:
{ "_id": ObjectId("58b99f08a7a2dfe1174e8eb9"), "players": [{ "name": "Oliver queen", "role": "pitcher" }] }
_如果您可以按角色拥有多个玩家(例如上面的模型中),请使用aggregation $filter
players
数组并使用匹配的角色:
db.players.aggregate([{
$match: {
"team": "Dragons",
"season": "2016-17",
"players.role": "pitcher"
}
}, {
$project: {
players: {
$filter: {
input: "$players",
as: "player",
cond: { $eq: ["$$player.role", "pitcher"] }
}
}
}
}])
这会给你:
{ "_id": ObjectId("58b99f08a7a2dfe1174e8eb9"), "players": [{ "name": "Oliver queen", "role": "pitcher" }, { "name": "SomeOne", "role": "pitcher" }] }
根据他们的位置显示所有球员的所有赛季 团队龙。
按players.role
使用汇总分组:
db.players.aggregate([{
$match: {
"team": "Dragons"
}
}, {
$unwind: "$players"
}, {
$group: {
_id: "$players.role",
players: {
$push: "$players.name"
}
}
}])
这给出了:
{ "_id": "catcher", "players": ["Slade Wilson", "Batman"] } { "_id": "pitcher", "players": ["Oliver queen", "SomeOne", "Joker"] }
更新特定季节中特定玩家的名称 特定的团队。 (例如,更新"投手"在2016-17赛季中 来自" Oliver Queen"到"绿箭"
使用匹配找到项目的positional parameter进行更新:
db.players.update({
"team": "Dragons",
"season": "2016-17",
"players.name": "Oliver queen"
}, {
$set: {
"players.$.name": "Green Arrow"
}
});
{
"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"
}
每个文档都包含特定团队中特定团队中的玩家
根据他们的位置(即'投手')显示单个玩家 特定团队的特定季节。例如,我想知道谁 投手是2015-16赛季的龙队。
db.players.find({ "team": "Dragons", "season": "2016-17", "role": "pitcher" })
根据他们的位置显示所有球员的所有赛季 团队龙。
db.players.find({"team": "Dragons", "role": "pitcher"})
更新特定季节中特定玩家的名称 特定的团队。 (例如,更新"投手"在2016-17赛季中 来自" Oliver Queen"到"绿箭"
db.players.update({
"team": "Dragons",
"season": "2016-17",
"name": "Oliver queen"
}, {
$set: {
"name": "Green Arrow"
}
})