目前,我有 3 个不同的聚合查询,它们根据 companyRegNo 的分组生成不同的计数。有没有办法结合这 3 个查询。
employeeActions 数据如下所示:
{
"email": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b4dbdad1f4d3d9d5ddd89ad7dbd9" rel="noreferrer noopener nofollow">[email protected]</a>",
"companyRegNo" : 105,
"event" : {
"created" : ISODate("2022-09-16T06:42:42.761Z"),
"desc" : "COMPLETED_APPLICATIONS",
"note" : "Direct apply",
}
}
{
"email": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e08f8e85a0878d81898cce838f8d" rel="noreferrer noopener nofollow">[email protected]</a>",
"companyRegNo" : 247,
"event" : {
"created" : ISODate("2022-09-16T06:42:04.387Z"),
"desc" : "COMPLETED_APPLICATIONS",
"note" : "",
}
}
{
"email": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e38c8d86a3848e828a8fcd808c8e" rel="noreferrer noopener nofollow">[email protected]</a>",
"companyRegNo" : 247,
"event" : {
"created" : ISODate("2022-09-16T06:42:42.761Z"),
"desc" : "COMPLETED_REVIEW",
"note" : ""Sent for review"",
}
}
{
"email": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b0dfded5f0d7ddd1d9dc9ed3dfdd" rel="noreferrer noopener nofollow">[email protected]</a>",
"companyRegNo" : 105,
"event" : {
"created" : ISODate("2022-09-16T06:42:42.761Z"),
"desc" : "COMPLETED_REVIEW",
"note" : "Data is complete",
}
}
{
"email": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d8b7b6bd98bfb5b9b1b4f6bbb7b5" rel="noreferrer noopener nofollow">[email protected]</a>",
"companyRegNo" : 247,
"event" : {
"created" : ISODate("2022-09-16T06:42:04.387Z"),
"desc" : "COMPLETED_OFFER",
"note" : "",
}
}
{
"email": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="eb84858eab8c868a8287c5888486" rel="noreferrer noopener nofollow">[email protected]</a>",
"companyRegNo" : 227,
"event" : {
"created" : ISODate("2022-09-16T06:42:04.387Z"),
"desc" : "COMPLETED_APPLICATIONS",
"note" : "",
}
}
{
"email": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8ffbf8e0cfe8e2eee6e3a1ece0e2" rel="noreferrer noopener nofollow">[email protected]</a>",
"companyRegNo" : 227,
"event" : {
"created" : ISODate("2022-09-16T06:42:42.761Z"),
"desc" : "COMPLETED_APPLICATIONS",
"note" : "",
}
}
{
"email": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b4c0c3dbf4d3d9d5ddd89ad7dbd9" rel="noreferrer noopener nofollow">[email protected]</a>",
"companyRegNo" : 105,
"event" : {
"created" : ISODate("2022-09-16T06:42:42.761Z"),
"desc" : "COMPLETED_APPLICATIONS",
"note" : "Direct apply",
}
}
这 3 个不同的查询是:
查询评论计数
db.getCollection('employeeActions').aggregate([
{"$match": {
"event.created": {"$gte": ISODate("2022-06-01 00:00:00.000Z")},
"$or": [ {"event.desc": "COMPLETED_REVIEW"}, {"event.note": "Sent for review"}],
}},
{"$group":{"_id":"$companyRegNo","count": {"$sum": 1 } } },
{"$project":{ "companyRegNo":"$_id","count": "$count","_id":0}}
])
结果将是
105 1
227 0
247 1
查询优惠计数
db.getCollection('employeeActions').aggregate([
{"$match": {
"event.created": {"$gte": ISODate("2022-06-01 00:00:00.000Z")},
"event.desc": "COMPLETED_OFFER"
}},
{"$group":{"_id":"$companyRegNo","count": {"$sum": 1 } } },
{"$project":{ "companyRegNo":"$_id","count": "$count","_id":0}},
])
结果将是
105 0
227 0
247 1
查询应用程序计数
db.getCollection('employeeActions').aggregate([
{"$match": {
"event.created": {"$gte": ISODate("2022-06-01 00:00:00.000Z")},
"event.desc": "COMPLETED_APPLICATIONS"
}},
{"$group":{"_id":"$companyRegNo","count": {"$sum": 1 } } },
{"$project":{ "companyRegNo":"$_id","count": "$count","_id":0}},
])
结果将是
105 2
227 2
247 1
有没有办法组合这 3 个查询,以便得到如下结果?
CompanyRegNo 应用程序评论优惠
105 2 1 0
227 2 0 0
247 1 1 1
我尝试使用 $facet 来组合这些查询。它为我提供了所有公司的总计 3 个计数。
"offers" : 1, "reviews" : 2, "applications" : 5
我需要将数据拆分到各个公司。
db.getCollection('employeeActions').aggregate([
{ "$match": { "event.created": {"$gte": ISODate("2022-01-01 00:00:00.000Z")}}},
{ "$facet": {
"offers": [
{"$match":{ "event.desc": "COMPLETED_OFFER" } },
{"$group":{"_id":"$companyRegNo","count": {"$sum": 1 } } },
{ "$count": "offers" },
],
"reviews": [
{"$match":{
"$or": [ {"event.desc": "COMPLETED_REVIEW"}, {"event.note": "Sent for review"}],
}},
{"$group":{"_id":"$companyRegNo","count": {"$sum": 1 }} },
{ "$count": "reviews" },
],
"applications": [
{"$match":{ "event.desc": "COMPLETED_APPLICATIONS" } },
{"$group":{"_id":"$companyRegNo","count":{"$sum": 1 }} },
{ "$count": "applications" },
]
}
},
{ "$project": {
"offers": { "$arrayElemAt": ["$offers.offers", 0] },
"reviews": { "$arrayElemAt": ["$reviews.reviews", 0] },
"applications": { "$arrayElemAt": ["$applications.applications", 0] }
}}
])```
最佳答案
虽然 @NeNaD 的答案被认为是“最佳实践”(我投票支持它),但由于 $facet
是针对此类情况创建的,因此重要的是要知道,还有其他选择。使用 $facet
也有缺点,其中之一是它将所有文档“合并”为一个大文档,并且文档有大小限制。如果您的集合很大,并且许多文档符合您的第一个条件,您可能需要考虑其他方法。
一种替代方法是将 $group
与 $cond
一起使用:
db.collection.aggregate([
{$match: {
"event.created": {$gte: ISODate("2022-06-01T00:00:00.000Z")}
}},
{$group: {
_id: "$companyRegNo",
ReviewCount: {
$sum: {$cond: [
{$or: [
{$eq: ["$event.desc", "COMPLETED_REVIEW"]},
{$eq: ["$event.note", "Sent for review"]}
]
}, 1, 0]}
},
OfferCount: {
$sum: {$cond: [{$eq: ["$event.desc", "COMPLETED_OFFER"]}, 1, 0]}
},
ApplicationsCount: {
$sum: {$cond: [{$eq: ["$event.desc", "COMPLETED_APPLICATIONS"]}, 1, 0]}
}
}
}
])
看看它在 playground example 上的工作原理
关于mongodb - 在 Mongo 聚合中,可以通过分组生成 3 个不同的计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73818175/