对数组中的文档进行排序
Sorting on documents within an array
我已经非常努力地阅读了有关查找和排序的文档,但没有成功。如果它不适合我想做的操作,我可以更改我的文档结构,但我更喜欢我当前的结构。
所有用户都有名字和一系列技能,每个人都有名字和相关的技能水平。所有用户在每项技能上都有技能水平。
这是我的结构:
{
"name": "Alice",
"skills": [
{
"name": "gardening",
"level": 10
},
{
"name": "shopping",
"level": 7
}
]
},
{
"name": "Bruce",
"skills": [
{
"name": "gardening",
"level": 5
},
{
"name": "shopping",
"level": 10
}
]
}
我有很多这样的对象,我将它们中的每一个都称为 Users
。我想按园艺技能对用户进行排序 level
。
我知道我可以访问 10 级 Users
,无论他们是 10 级的哪个技能,使用查找查询:
{ 'skills.level' : 10 }
但我想按用户的园艺技能水平对用户进行排序,排序命令如下:
{ "skills.gardening.level" : 1 }
但由于我当前的结构,这不起作用。
我是否需要更改我的结构才能像这样排序,或者我可以让它工作吗?
您可以在不更改文档结构的情况下进行这项工作,但代价是该操作不会使用索引,并且对于很多用户来说会非常慢。使用聚合框架:
> db.users.aggregate([
{ "$unwind" : "$skills" },
{ "$match" : { "skills.name" : "gardening" } }
{ "$sort" : { "skills.level" : 1 } }
])
{ "_id" : ObjectId(...), "name" : "Bruce", "skills" : { "name" : "gardening", "level" : 5 } }
{ "_id" : ObjectId(...), "name" : "Alice", "skills" : { "name" : "gardening", "level" : 10 } }
在没有关于您如何使用集合的任何其他信息的情况下,允许您按个人技能水平排序的最简单更改是重新设计文档,以便一个文档代表一个用户的一种技能:
{
"name" : "Alice",
"skill" : "gardening",
"level" : 10
}
针对特定 skill
按 level
排序:
db.skills.find({ "skill" : "gardening" }).sort({ "level" : 1 })
{ "skill" : 1, "level" : 1 }
上的索引。
正在检索具有与旧用户文档等效信息的文档集合:
db.skills.find({ "name" : "Alice" })
{ "name" : 1 }
上的索引。
我已经非常努力地阅读了有关查找和排序的文档,但没有成功。如果它不适合我想做的操作,我可以更改我的文档结构,但我更喜欢我当前的结构。
所有用户都有名字和一系列技能,每个人都有名字和相关的技能水平。所有用户在每项技能上都有技能水平。
这是我的结构:
{
"name": "Alice",
"skills": [
{
"name": "gardening",
"level": 10
},
{
"name": "shopping",
"level": 7
}
]
},
{
"name": "Bruce",
"skills": [
{
"name": "gardening",
"level": 5
},
{
"name": "shopping",
"level": 10
}
]
}
我有很多这样的对象,我将它们中的每一个都称为 Users
。我想按园艺技能对用户进行排序 level
。
我知道我可以访问 10 级 Users
,无论他们是 10 级的哪个技能,使用查找查询:
{ 'skills.level' : 10 }
但我想按用户的园艺技能水平对用户进行排序,排序命令如下:
{ "skills.gardening.level" : 1 }
但由于我当前的结构,这不起作用。
我是否需要更改我的结构才能像这样排序,或者我可以让它工作吗?
您可以在不更改文档结构的情况下进行这项工作,但代价是该操作不会使用索引,并且对于很多用户来说会非常慢。使用聚合框架:
> db.users.aggregate([
{ "$unwind" : "$skills" },
{ "$match" : { "skills.name" : "gardening" } }
{ "$sort" : { "skills.level" : 1 } }
])
{ "_id" : ObjectId(...), "name" : "Bruce", "skills" : { "name" : "gardening", "level" : 5 } }
{ "_id" : ObjectId(...), "name" : "Alice", "skills" : { "name" : "gardening", "level" : 10 } }
在没有关于您如何使用集合的任何其他信息的情况下,允许您按个人技能水平排序的最简单更改是重新设计文档,以便一个文档代表一个用户的一种技能:
{
"name" : "Alice",
"skill" : "gardening",
"level" : 10
}
针对特定 skill
按 level
排序:
db.skills.find({ "skill" : "gardening" }).sort({ "level" : 1 })
{ "skill" : 1, "level" : 1 }
上的索引。
正在检索具有与旧用户文档等效信息的文档集合:
db.skills.find({ "name" : "Alice" })
{ "name" : 1 }
上的索引。