【问题标题】:MongoDB: How can I filter specific Value from aggregate stage?MongoDB:如何从聚合阶段过滤特定值?
【发布时间】:2021-07-09 15:48:20
【问题描述】:

我的汇总代码

 const temp = await Employee.aggregate([
      {
        $unwind: { path: '$timeClocks', preserveNullAndEmptyArrays: true },
      },

      {
        $match: {
          _id: { $in: employees },
        },
      },

      {
        $group: {
          _id: '$_id',
          name: { $first: '$name' },
          timeClock: {
            $push: {
              start_time: '$timeClocks.start_time',
              end_time: '$timeClocks.end_time',
            },
          },
        },
      },
      // {
      //   $match: {
      //     timeClock: {
      //       start_time: new Date('2021-05-10'),
      //     },
      //   },
      // },
      // {
      //   $match: {
      //     timeClock: {
      //       start_time: {
      //         $gte: 'moment.utc(date).toDate()',
      //       },
      //     },
      //   },
      // },
      {
        $project: {
          name: 1,
          timeClock: 1,
        },
      },
    ]);

结果

"working": [
      {
          "_id": "60cd9a3cb4ddcc00285b0df9",
          "name": "Dr. dd",
          "timeClock": [
              {
                  "start_time": "2021-05-04T02:19:00.000Z",
                  "end_time": "2021-05-04T14:42:00.000Z"
              },
              {
                  "start_time": "2021-05-02T08:12:00.000Z",
                  "end_time": "2021-05-02T22:24:00.000Z"
              },
              {
                  "start_time": "2021-05-10T20:14:00.000Z",
                  "end_time": "2021-05-10T22:17:00.000Z"
              },
          ]
      },
  ],

我现在的情况是,当我从集合中聚合时,我在 timeClock 字段中获得了多个值。但我想在timeClock 字段中有一个匹配日期。 例如,如果我想要一个日期(2021-05-10),那么

预期结果

"working": [
      {
          "_id": "60cd9a3cb4ddcc00285b0df9",
          "name": "Dr. dd",
          "timeClock": {
                  "start_time": "2021-05-10T02:19:00.000Z",
                  "end_time": "2021-05-1-T14:42:00.000Z"
              },
      },
  ],

我尝试添加$match$filter,但给了我一个空数组。

我是 MongoDB 新手,谁能告诉我聚合阶段缺少什么?

【问题讨论】:

    标签: node.js mongodb aggregation-framework


    【解决方案1】:

    匹配日期(或日期字符串)的“问题”是需要完全匹配。

    我将展示如何为 Date 类型解决此问题(如果您的数据是字符串,那么我将在最后简要说明哪种方法适用于此)。

    因此我们的方法是使用$dateFromParts 将转换start_time 字段转换为可比较的,如下所示:

    const inputDate = new Date('2020-05-10');
    
    ....
    
    
    [
        {
            $unwind: { path: '$timeClocks', preserveNullAndEmptyArrays: true },
        },
        {
            $match: {
                _id: { $in: employees },
            },
        },
        {
            $match: {
                $expr: {
                    $eq: [
                        {
                            $dateFromParts : {
                                year: {$year: '$timeClocks.start_time'},
                                month: {$month: '$timeClocks.start_time'},
                                day: {$dayOfMonth: '$timeClocks.start_time'},
                            }
                        },
                        inputDate
                    ]
                }
            },
        },
        {
            $group: {
                _id: '$_id',
                name: { $first: '$name' },
                timeClock: {
                    $push: {
                        start_time: '$timeClocks.start_time',
                        end_time: '$timeClocks.end_time',
                    },
                },
            },
        },
       // in your example this will be an array with 1 element. if this 
       //is always the case you can just use `$first` instead of `$push`.
    ]
    

    如果您的日期保存为 string,那么您可以使用 $toDate 对其进行转换,如果您使用的是 Mongo v4.0+,则可以使用相同的管道。 您还可以比较字符串并在T 上使用$split,以便"2021-05-04T02:19:00.000Z" 变成"2021-05-04" 但是我从不建议在日期方面匹配字符串,以及您需要支持的各种问题(如时区/夏令时等等)您还必须保证所有字符串的格式都相同才能正常工作。

    【讨论】:

    • 非常感谢您抽出时间回答我的问题。我能够得到预期的结果!我想知道管道是否逐级从上到下执行?或者它可能没有被订购,但最后阶段是结果?
    • 很抱歉,由于我的英语水平,我的问题没有得到很好的解释
    • 从上到下,逐步执行。我不确定你的确切意思,但每个阶段都不能“独立”运行
    • 再次感谢您的回答我想我现在了解阶段的工作原理!非常感谢
    猜你喜欢
    • 2021-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-21
    • 1970-01-01
    • 2021-02-28
    • 1970-01-01
    相关资源
    最近更新 更多