以下是MongoDB教程的示例(此处为集合ZIP Code db:
db.zipcodes.aggregate( [
{ $group: { _id: "$state", totalPop: { $sum: "$pop" } } },
{ $match: { totalPop: { $gte: 10*1000*1000 } } }
] )
如果我将_id
替换为其他字词Test
,我会收到错误消息:
"errmsg" : "exception: the group aggregate field 'Test' must be defined as an expression inside an object",
"code" : 15951,
"ok" : 0
有人能帮助我理解为什么我的命令需要_id
吗?我认为MongoDB会自动分配ID,如果使用则不提供ID。
答案 0 :(得分:6)
在$group
阶段,_id
用于指定组条件。你显然需要它。
如果您熟悉SQL世界,请将其视为GROUP BY
子句。
请注意,在该上下文中,_id
实际上是生成的集合中的唯一标识符,因为根据定义$group
不能生成具有该字段相同值的两个文档。 /子>
答案 1 :(得分:5)
我们将了解_id
阶段内的$group
字段&查看在组聚合阶段构建_id
的一些最佳实践。我们来看看这个查询:
db.companies.aggregate([{
$match: {
founded_year: {
$gte: 2010
}
}
}, {
$group: {
_id: {
founded_year: "$founded_year"
},
companies: {
$push: "$name"
}
}
}, {
$sort: {
"_id.founded_year": 1
}
}]).pretty()
我们可能不清楚的一件事是为什么_id
字段是以这种“文档”方式构建的?我们也可以这样做:
db.companies.aggregate([{
$match: {
founded_year: {
$gte: 2010
}
}
}, {
$group: {
_id: "$founded_year",
companies: {
$push: "$name"
}
}
}, {
$sort: {
"_id": 1
}
}]).pretty()
我们不是这样做的,因为在这些输出文件中 - 这个数字究竟意味着什么并不明确。所以,我们实际上不知道。在某些情况下,这意味着在解释这些文件时可能会有困惑。因此,另一种情况可能是将_id
文档分组为多个字段:
db.companies.aggregate([{
$match: {
founded_year: {
$gte: 2010
}
}
}, {
$group: {
_id: {
founded_year: "$founded_year",
category_code: "$category_code"
},
companies: {
$push: "$name"
}
}
}, {
$sort: {
"_id.founded_year": 1
}
}]).pretty()
$push
只是将元素推送到生成数组。通常,可能需要将提升的字段分组到较高级别:
db.companies.aggregate([{
$group: {
_id: {
ipo_year: "$ipo.pub_year"
},
companies: {
$push: "$name"
}
}
}, {
$sort: {
"_id.ipo_year": 1
}
}]).pretty()
将表达式解析为文档作为_id
密钥也是完美的。
db.companies.aggregate([{
$match: {
"relationships.person": {
$ne: null
}
}
}, {
$project: {
relationships: 1,
_id: 0
}
}, {
$unwind: "$relationships"
}, {
$group: {
_id: "$relationships.person",
count: {
$sum: 1
}
}
}, {
$sort: {
count: -1
}
}])
答案 2 :(得分:4)
_id
字段是必填字段,但如果不希望根据密钥或密钥进行汇总,则可以将其设置为null
。不使用它将导致字段上的单个聚合值。因此,它在此上下文中表示“保留字”,指示每个组产生的“标识符”/键是什么。
在您的情况下,按_id: "$state"
分组会产生n
totalPop
的汇总结果,前提是n
有state
个不同的值(类似)到SELECT SUM() FROM table GROUP BY state
)。然而,
$group : {_id : null, totalPop: { $sum: "$pop" }}}
会为totalPop
提供单一结果(类似于SELECT SUM() FROM table
)。
组操作符documentation中详细描述了此行为。