聚合查询无法正确处理日期 $lte 和 $gte

问题描述 投票:0回答:1

如果日期范围是 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": {}
            }
            }
javascript mongodb mongoose aggregate
1个回答
0
投票

我通过添加 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' }],
        },
      },
    },
  ]);
© www.soinside.com 2019 - 2024. All rights reserved.