所以我希望将我的收藏中的文档分组到特定字段,并且对于每个组的输出结果,我希望包含以下内容:
我对用于在mongo中查询的语法很新,并且不太了解它是如何工作的,但经过一些研究后,我设法将其归结为以下查询(请注意,我目前正在使用3.0.12版本用于我的mongo db,但我相信我们会在几个月后升级):
db.getCollection('myCollection').aggregate(
[
{
$group: {
_id: {
GroupID: "$GroupID",
Status: "$Status"
},
total: { $sum: 1 },
GroupName: { $first: "$GroupName" },
EarliestCreatedDate: { $min: "$DateCreated" },
LastModifiedDate: { $max: "$LastModifiedDate" }
}
},
{
$group: {
_id: "$_id.GroupID",
Statuses: {
$push: {
Status: "$_id.Status",
Count: "$total"
}
},
TotalCount: { $sum: "$total" },
GroupName: { $first: "$GroupName" },
EarliestCreatedDate: { $min: "$EarliestCreatedDate" },
LastModifiedDate: { $max: "$LastModifiedDate" }
}
}
]
)
基本上我要检索的是Count for specific Status值,并将它们投影到一个最终结果文档中,如下所示:
{
GroupName,
EarliestCreatedDate,
EarliestCreatedBy,
LastModifiedDate,
LastModifiedBy,
TotalCount,
PendingCount,
ClosedCount
}
PendingCount和ClosedCount是每个组中具有Pending / Closed状态的文档总数。我怀疑我需要使用带有其他表达式的$ project来提取这个值,但是我并不能很好地理解聚合管道以便解决这个问题。
EarliestCreatedBy和LastModifiedBy也是分别创建/修改与EarliestCreatedDate和LastModifiedDate相对应的文档的用户。正如我所提到的,我认为检索这些值会增加另一层复杂性,所以如果没有实际的解决方案,我愿意放弃这个要求。
非常感谢任何建议/提示。
答案 0 :(得分:1)
您可以尝试以下聚合阶段。
$group
为每个TotalCount
计算所有必要的计数PendingCount
,ClosedCount
和GroupID
分别为$min
和$max
计算EarliestCreatedDate
和LastModifiedDate
,并push
将CreatedByLastModifiedBy
的所有字段稍后进行比较以获取EarliestCreatedBy
{每个LastModifiedBy
GroupID
$project
投放所有响应字段
$filter
EarliestCreatedDate
对CreatedByLastModifiedBy
和$map
数据CreatedBy
的匹配EarliestCreatedBy
与$arrayElemAt
和LastModifiedBy
将数组转换为object。
计算db.getCollection('myCollection').aggregate(
[{
$group: {
_id: "$GroupID",
TotalCount: {
$sum: 1
},
PendingCount: {
$sum: {
$cond: {
if: {
$eq: ["Status", "Pending"]
},
then: 1,
else: 0
}
}
},
ClosedCount: {
$sum: {
$cond: {
if: {
$eq: ["Status", "Closed "]
},
then: 1,
else: 0
}
}
},
GroupName: {
$first: "$GroupName"
},
EarliestCreatedDate: {
$min: "$DateCreated"
},
LastModifiedDate: {
$max: "$LastModifiedDate"
},
CreatedByLastModifiedBy: {
$push: {
CreatedBy: "$CreatedBy",
LastModifiedBy: "$LastModifiedBy",
DateCreated: "$DateCreated",
LastModifiedDate: "$LastModifiedDate"
}
}
}
}, {
$project: {
_id: 0,
GroupName: 1,
EarliestCreatedDate: 1,
EarliestCreatedBy: {
$arrayElemAt: [{
$map: {
input: {
$filter: {
input: "$CreatedByLastModifiedBy",
as: "CrBy",
cond: {
"$eq": ["$EarliestCreatedDate", "$$CrBy.DateCreated"]
}
}
},
as: "EaCrBy",
in: {
"$$EaCrBy.CreatedBy"
}
}
}, 0]
},
LastModifiedDate: 1,
LastModifiedBy: {
$arrayElemAt: [{
$map: {
input: {
$filter: {
input: "$CreatedByLastModifiedBy",
as: "MoBy",
cond: {
"$eq": ["$LastModifiedDate", "$$MoBy.LastModifiedDate"]
}
}
},
as: "LaMoBy",
in: {
"$$LaMoBy.LastModifiedBy"
}
}
}, 0]
},
TotalCount: 1,
PendingCount: 1,
ClosedCount: 1
}
}]
)
$filter
版本更新< 3.2
false
在您的版本中也不可用。以下是等效的。
比较逻辑是相同的,并创建一个数组,其中每个非匹配条目的值为LastModifiedBy
或$setDifference
。
下一步是使用[false]
将先前的数组值与数组LastModifiedBy: {
$setDifference: [{
$map: {
input: "$CreatedByLastModifiedBy",
as: "MoBy",
in: {
$cond: [{
$eq: ["$LastModifiedDate", "$$MoBy.LastModifiedDate"]
},
"$$MoBy.LastModifiedBy",
false
]
}
}
},
[false]
]
}
进行比较,后者返回仅存在于第一组中的元素。
$unwind
在$project
阶段之后添加{$unwind:"$LastModifiedBy"}
阶段以更改为对象
EarliestCreatedBy
计算{{1}}
的类似步骤