mongodb $聚合空数组和多个文档
mongodb $aggregate empty array and multiple documents
mongodb 有以下文件:
> db.test.find({name:{$in:["abc","abc2"]}})
{ "_id" : 1, "name" : "abc", "scores" : [ ] }
{ "_id" : 2, "name" : "abc2", "scores" : [ 10, 20 ] }
我想获取每个文档的 scores 数组长度,我应该怎么做?
尝试了以下命令:
db.test.aggregate({$match:{name:"abc2"}}, {$unwind: "$scores"}, {$group: {_id:null, count:{$sum:1}}} )
结果:
{ "_id" : null, "count" : 2 }
但是下面的命令:
db.test.aggregate({$match:{name:"abc"}}, {$unwind: "$scores"}, {$group: {_id:null, count:{$sum:1}}} )
Return 没有。问题:
- 我应该如何在一个文档中获取 2 个或更多文档中的每个分数长度
命令?
- 为什么第二个命令的结果return什么都没有?如何
我应该检查数组是否为空?
所以这实际上是一个普遍的问题。数组为 "empty" 的聚合管道中 $unwind
阶段的结果是 "remove" 以记录管道结果。
为了 return 这样一个 "empty" 数组的“0”计数,您需要执行以下操作。
在 MongoDB 2.6 或更高版本中,只需使用 $size
:
db.test.aggregate([
{ "$match": { "name": "abc" } },
{ "$group": {
"_id": null,
"count": { "$sum": { "$size": "$scores" } }
}}
])
在早期版本中你需要这样做:
db.test.aggregate([
{ "$match": { "name": "abc" } },
{ "$project": {
"name": 1,
"scores": {
"$cond": [
{ "$eq": [ "$scores", [] ] },
{ "$const": [false] },
"$scores"
]
}
}},
{ "$unwind": "$scores" },
{ "$group": {
"_id": null,
"count": { "$sum": {
"$cond": [
"$scores",
1,
0
]
}}
}}
])
现代操作很简单,因为 $size
只是 "measure" 数组。在后一种情况下,当数组为空时,您需要 "replace" 具有单个 false
值的数组,以避免 $unwind
"destroying" 对于 "empty" 语句。
所以替换为 false
允许整个语句的 $cond
"trinary" to choose whether to add 1
or 0
to the $sum
。
这就是你如何得到 "empty arrays" 的长度。
要获得 2 个或更多文档的分数长度,您只需更改 $group
管道中的 _id
值,其中包含不同的按键分组,所以在这种情况下,您需要按文档 _id
分组。
您的第二个聚合 returns 没有,因为 $match
查询管道传递了一个分数数组为空的文档。要检查数组是否为空,您的匹配查询应该是
{'scores.0': {$exists: true}}
或 {scores: {$not: {$size: 0}}}
总体而言,您的聚合应如下所示:
db.test.aggregate([
{ "$match": {"scores.0": { "$exists": true } } },
{ "$unwind": "$scores" },
{
"$group": {
"_id": "$_id",
"count": { "$sum": 1 }
}
}
])
mongodb 有以下文件:
> db.test.find({name:{$in:["abc","abc2"]}})
{ "_id" : 1, "name" : "abc", "scores" : [ ] }
{ "_id" : 2, "name" : "abc2", "scores" : [ 10, 20 ] }
我想获取每个文档的 scores 数组长度,我应该怎么做?
尝试了以下命令:
db.test.aggregate({$match:{name:"abc2"}}, {$unwind: "$scores"}, {$group: {_id:null, count:{$sum:1}}} )
结果:
{ "_id" : null, "count" : 2 }
但是下面的命令:
db.test.aggregate({$match:{name:"abc"}}, {$unwind: "$scores"}, {$group: {_id:null, count:{$sum:1}}} )
Return 没有。问题:
- 我应该如何在一个文档中获取 2 个或更多文档中的每个分数长度 命令?
- 为什么第二个命令的结果return什么都没有?如何 我应该检查数组是否为空?
所以这实际上是一个普遍的问题。数组为 "empty" 的聚合管道中 $unwind
阶段的结果是 "remove" 以记录管道结果。
为了 return 这样一个 "empty" 数组的“0”计数,您需要执行以下操作。
在 MongoDB 2.6 或更高版本中,只需使用 $size
:
db.test.aggregate([
{ "$match": { "name": "abc" } },
{ "$group": {
"_id": null,
"count": { "$sum": { "$size": "$scores" } }
}}
])
在早期版本中你需要这样做:
db.test.aggregate([
{ "$match": { "name": "abc" } },
{ "$project": {
"name": 1,
"scores": {
"$cond": [
{ "$eq": [ "$scores", [] ] },
{ "$const": [false] },
"$scores"
]
}
}},
{ "$unwind": "$scores" },
{ "$group": {
"_id": null,
"count": { "$sum": {
"$cond": [
"$scores",
1,
0
]
}}
}}
])
现代操作很简单,因为 $size
只是 "measure" 数组。在后一种情况下,当数组为空时,您需要 "replace" 具有单个 false
值的数组,以避免 $unwind
"destroying" 对于 "empty" 语句。
所以替换为 false
允许整个语句的 $cond
"trinary" to choose whether to add 1
or 0
to the $sum
。
这就是你如何得到 "empty arrays" 的长度。
要获得 2 个或更多文档的分数长度,您只需更改 $group
管道中的 _id
值,其中包含不同的按键分组,所以在这种情况下,您需要按文档 _id
分组。
您的第二个聚合 returns 没有,因为 $match
查询管道传递了一个分数数组为空的文档。要检查数组是否为空,您的匹配查询应该是
{'scores.0': {$exists: true}}
或 {scores: {$not: {$size: 0}}}
总体而言,您的聚合应如下所示:
db.test.aggregate([
{ "$match": {"scores.0": { "$exists": true } } },
{ "$unwind": "$scores" },
{
"$group": {
"_id": "$_id",
"count": { "$sum": 1 }
}
}
])