[英]MongoDB aggregate return count of documents or 0
我有以下聚合查询:
db.user.aggregate()
.match({"business_account_id" : ObjectId("5e3377bcb1dbae5124e4b6bf")})
.lookup({
'localField': 'profile_id',
'from': 'profile',
'foreignField' : '_id',
'as': 'profile'
})
.unwind("$profile")
.match({"profile.type" : "consultant"})
.group({_id:"$business_account_id", count:{$sum:1}})
我的目标是计算有多少顾问用户属于给定的公司。
使用上面的查询,如果至少有一个用户属于提供的 business_account_id,我会得到一个正确的计数值。
但如果没有用户, .match({"business_account_id": ObjectId("5e3377bcb1dbae5124e4b6bf")})
将返回空(0 个文档)结果。
如果没有分配给公司的用户,我如何获得count: 0
?
我尝试了许多基于其他线程的方法,但我无法count: 0
更新 1
我的问题的一个简单版本:
用户集合
{
"_id" : ObjectId("5e36beb7b1dbae5124e4b6dc"),
"business_account_id" : ObjectId("5e3377bcb1dbae5124e4b6bf"),
},
{
"_id" : ObjectId("5e36d83db1dbae5124e4b732"),
"business_account_id" : ObjectId("5e3377bcb1dbae5124e4b6bf"),
}
使用以下聚合查询:
db.getCollection("user").aggregate([
{ "$match" : {
"business_account_id" : ObjectId("5e3377bcb1dbae5124e4b6bf")
}
},
{ "$group" : {
"_id" : "$business_account_id",
"count" : { "$sum" : 1 }
}
}
]);
我得到:
{
"_id" : ObjectId("5e3377bcb1dbae5124e4b6bf"),
"count" : 2
}
但是,如果我查询一个不存在的 ObjectId,例如:
db.getCollection("user").aggregate([
{ "$match" : {
"business_account_id" : ObjectId("5e335c873e8d40676928656d")
}
},
{ "$group" : {
"_id" : "$business_account_id",
"count" : { "$sum" : 1 }
}
}
]);
我得到一个完全空的结果。 我希望得到:
{
"_id" : ObjectId("5e335c873e8d40676928656d"),
"count" : 0
}
由于您匹配不存在的business_account_id
值,聚合过程将停止。
解决方法:如果匹配没有结果,我们使用$facet运算符并行执行 2 次聚合以获取default
值。
注意:确保user
集合至少有 1 条记录,否则这将不起作用
db.user.aggregate([
{
$facet: {
not_found: [
{
$project: {
"_id": ObjectId("5e3377bcb1dbae5124e4b6bf"),
"count": { $const: 0 }
}
},
{
$limit: 1
}
],
found: [
{
"$match": {
"business_account_id": ObjectId("5e3377bcb1dbae5124e4b6bf")
}
},
{
"$group": {
"_id": "$business_account_id",
"count": { "$sum": 1 }
}
}
]
}
},
{
$replaceRoot: {
newRoot: {
$mergeObjects: [
{
$arrayElemAt: ["$not_found", 0]
},
{
$arrayElemAt: ["$found", 0]
}
]
}
}
}
])
问题的根源在于,如果user
集合中没有满足初始$match
的文档,则没有任何内容可以传递到管道的下一阶段。 如果business_account_id
确实存在于某处(可能是另一个集合?),则针对该集合运行聚合,以便初始匹配找到至少一个文档。 然后使用 $lookup 查找用户。 如果您使用的是 MongoDB 3.6+,您可以结合用户和配置文件查找。 最后,使用$size
计算 users 数组中的元素。
(您可能需要调整集合和字段名称)
db.businesses.aggregate([
{$match:{_id : ObjectId("5e3377bcb1dbae5124e4b6bf")}},
{$project: { _id:1 }},
{$lookup:{
from: "users",
let: {"busId":"$_id"},
as: "users",
pipeline: [
{$match: {$expr:{$eq:[
"$$busId",
"$business_account_id"
]}}},
{$lookup:{
localField: "profile_id",
from: "profile",
foreignField : "_id",
as: "profile"
}},
{$match: { "profile.type" : "consultant"}}
]
}},
{$project: {
_id: 0,
business_account_id: "$_id",
count:{$size:"$users"}
}}
])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.