如果日期范围是 2 天,例如 开始日期 = 2023-11-26 结束日期 = 2023-11-27 一切正常,当日期相等时,活动数组为空,如何使 $gte 和 $lte 比较工作?我确信今天的数据是存在的,问题出在聚合部分
async getCampaigns(query, res) {
console.log(query);
try {
let { offset = 0, limit = 30, startDate, endDate } = query;
const startDateString = startDate;
endDate = new Date(endDate);
offset = parseInt(offset);
limit = Math.min(
parseInt(limit),
await this.campaignModel.countDocuments(),
);
startDate = startDate
? new Date(startDate)
: new Date(endDate.getTime() - 14 * 24 * 60 * 60 * 1000);
if (isNaN(offset) || isNaN(limit)) {
throw new BadRequestError('Invalid offset or limit');
}
const dates = getAllDatesBetween(`${startDateString}/${endDate}`);
const campaigns = await this.campaignModel.aggregate([
{ $addFields: { datesArray: { $objectToArray: '$dates' } } },
{ $unwind: '$datesArray' },
{
$match: {
'datesArray.k': {
$gte: startDate.toISOString(),
$lte: endDate.toISOString(),
},
},
},
{
$group: {
_id: '$_id',
totalCost: { $sum: '$datesArray.v.cost' },
document: { $first: '$$ROOT' },
},
},
{ $sort: { totalCost: -1 } },
{ $skip: offset },
{ $limit: limit },
{
$replaceRoot: {
newRoot: {
$mergeObjects: ['$document', { totalCost: '$totalCost' }],
},
},
},
]);
console.log(campaigns);
...
} catch (error) {
throw new InternalServerError('Internal Server Error');
}}
更新:根据要求添加了示例文档 输入文档(活动):
{
"_id": "666",
"trafficSourceName": "bla",
"name": "Sorry",
"keyword": "What Happens At A Cremation Australia",
"status": "active",
"limitsFilter": {
"limitType": "budget_limits",
"dailyLimit": 7500,
"overallLimit": 100000000,
"splitDailyLimitEvenly": 0
},
dates: {
"2023-11-25": {},
"2023-11-26": {},
"2023-11-27": {}
}
},{
"_id": "444",
"trafficSourceName": "bla",
"name": "Sorry",
"keyword": "What Happens At A Cremation United States",
"status": "active",
"limitsFilter": {
"limitType": "budget_limits",
"dailyLimit": 20000,
"overallLimit": 100000000,
"splitDailyLimitEvenly": 0
}, dates: {
"2023-11-25": {},
"2023-11-26": {},
"2023-11-27": {}
}
}
我通过添加 startDate 作为日期键解决了这个问题。因此,如果密钥存在 - 这个满足条件,我使用 ISOString 进行日期比较,因为这是 MongoDB 文档中编写的内容。
const campaigns = await this.campaignModel.aggregate([
{ $addFields: { datesArray: { $objectToArray: '$dates' } } },
{ $unwind: '$datesArray' },
{
$match: startDate.toISOString().split('T')[0] != endDate.toISOString().split('T')[0] ? {
'datesArray.k':
{
$gte: startDate.toISOString(),
$lte: endDate.toISOString(),
},
} : {
'datesArray.k': startDate.toISOString().split('T')[0]
},
},
{
$group: {
_id: '$_id',
totalCost: { $sum: '$datesArray.v.cost' },
document: { $first: '$$ROOT' },
},
},
{ $sort: { totalCost: -1 } },
{ $skip: offset },
{ $limit: limit },
{
$replaceRoot: {
newRoot: {
$mergeObjects: ['$document', { totalCost: '$totalCost' }],
},
},
},
]);