我有一个包含以下文档的客户集合:
{
"_id": 1,
firstname: "John",
lastname: "Doe",
credits: [
{
cDate: "2020-01-16",
cAmount: 350
},
{
cDate: "2021-02-07",
cAmount: 180
},
{
cDate: "2021-06-25",
cAmount: 650
},
]
}
{
"_id": 2,
firstname: "Bob",
lastname: "Smith",
credits: [
{
cDate: "2020-03-19",
cAmount: 200
},
{
cDate: "2020-08-20",
cAmount: 90
},
{
cDate: "2021-11-11",
cAmount: 300
},
]
}
现在我想返回特定年份(即2021年)的总支出。
数据应如下所示:
{"firstname": "John", "lastname": "Doe", "total": 830},
{"firstname": "Bob", "lastname": "Smith", "total": 300}
首先,我尝试匹配预期年份(2021)内包含cDates
的记录,以减少记录数量(实际数据集有数百个客户),然后投影所需字段:
Customer.aggregate([
{
$match: {
credits: {
$elemMatch: {
cDate: {
$gte: ISODate("2021-01-01"),
$lte: ISODate("2021-12-31"),
},
},
},
},
},
{
$project: {
_id: 0,
firstname: 1,
lastname: 1,
total: {
$sum: "$credits.cAmount",
},
},
}
])
结果是:
{"firstname": "John", "lastname": "Doe", "total": 1180},
{"firstname": "Bob", "lastname": "Smith", "total": 590}
差不多了,现在我想跳过不包含预期年份(2021)的信用记录,这样就只计算cDate
等于2021的值。$match
保持不变,我尝试在$project
位中添加一个$cond
。
Customer.aggregate([
{
$match: {
credits: {
$elemMatch: {
cDate: {
$gte: ISODate("2021-01-01"),
$lte: ISODate("2021-12-31"),
},
},
},
},
},
{
$project: {
_id: 0,
firstname: 1,
lastname: 1,
total: {
$cond: {
if: { credits: { cDate: { regex: "2021-" } } }, // if cDate contains 2021-
then: { $sum: "$credits.cAmount" }, // add the cAmount
else: { $sum: 0 } // else add 0
},
},
},
}
])
这个结果仍然是一样的,所有的总数都是从所有年份计算出来的。
{"firstname": "John", "lastname": "Doe", "total": 1180},
{"firstname": "Bob", "lastname": "Smith", "total": 590}
我错过了什么?
谢谢你的帮助。
1条答案
按热度按时间egdjgwm81#
属性
cDate
有字符串值,不能按日期类型匹配。$match
cDate
乘以$regex
并匹配"2021"
年$reduce
迭代credits
数组的循环,将初始值设置为0$substr
以从0索引和4个字符(年份)中获取cDate
的子字符串$cond
检查子串是否为"2021"
,然后$sum
初始值为cAmount
,否则返回初始值Playground