排序必须包含数组名称,以避免稍后进行额外的排序。
给定以下文档:
{
students: [{
count: 4,
name: "Ann"
}, {
count: 7,
name: "Brad"
}, {
count: 6,
name: "Beth"
}, {
count: 8,
name: "Catherine"
}]
}
例如,以下聚合查询将匹配任何包含字母“h”和“e”的名称。这需要在“$unwind”步骤之后进行,以便只保留您需要的那些。
db.tests.aggregate([
{$match: {
_id: ObjectId("5c1b191b251d9663f4e3ce65")
}},
{$unwind: {
path: "$students"
}},
{$match: {
"students.name": /[he]/
}},
{$sort: {
"students.count": -1
}},
{$limit: 2}
])
这是给定上述输入的输出:
{ "_id" : ObjectId("5c1b191b251d9663f4e3ce65"), "students" : { "count" : 8, "name" : "Catherine" } }
{ "_id" : ObjectId("5c1b191b251d9663f4e3ce65"), "students" : { "count" : 6, "name" : "Beth" } }
两个名字都包含字母“h”和“e”,输出从高到低排序。
将limit设置为1时,输出限制为:
{ "_id" : ObjectId("5c1b191b251d9663f4e3ce65"), "students" : { "count" : 8, "name" : "Catherine" } }
在这种情况下,只有在匹配名称后才会保留最高计数。
======================
编辑额外的问题:
是的,第一个 $match 可以更改为过滤特定大学。
{$match: {
university: "University X"
}},
这将提供一个或多个匹配的文档(如果您每年大约有一个文档),其余的聚合步骤仍然有效。
如果需要,以下匹配将检索给定大学在给定学年的学生。
{$match: {
university: "University X",
academic_year: "2018-2019"
}},
这应该缩小范围以获得正确的文档。