【问题标题】:mongodb aggregation with $last,$first updating values with zero if no record foundmongodb 聚合 $last,$first 如果未找到记录,则将值更新为零
【发布时间】:2020-03-20 13:04:52
【问题描述】:

请检查此查询

db.orders.aggregate([
    {
        '$match': {
            "userId" : ObjectId("5e7147ada3141a63a0dbc154"),
        "adminId" :  ObjectId("5e7147e8fc64ed3d2473o2fec"),
            '$or': [{
                    'orderedOnDate': ISODate("2020-03-21T00:00:00Z")
                    }, 
                     {
                      'orderedOnDate': ISODate("2020-03-14T00:00:00Z")
                    }]
              }
         }, 
        {
        '$unwind': {
            'path': '$totalOrders',
          },
        },
       {
        '$group': {
            '_id': {
                'code': '$totalOrders.code',
                'date': '$orderedOnDate',
            },
            'orderCount': {
                '$last': '$totalOrders.orderCount',
            },
             'sortedDate': {
                '$last': '$orderedOnDate'
            }
        }
    }
    , {
        '$sort': {
            'sortedDate': 1
        }
    }, {
        '$group': {
            '_id': '$_id.code',
            'orderCount': {
                '$last': '$orderCount'
            },
            'previousOrderCount': {
                '$first': '$previousOrderCount'
            },
           'sortedDate': {
                '$last': '$sortedDate'
            },
            'previousSortedDate': {
                '$first': '$sortedDate'
            },

        }
    },
      {
        '$project': {
            "_id": 0,
           'code':1
            'sortedDate': 1,
            'orderCount': 1,
            'previousWeekCount': [
                {
                    'sortedDate': '$previousOrderCount',
                    'orderCount': '$previousOrderCount',

                }
            ]
        }
    }])

在上面的查询中,我试图获取明天日期和 D-7 日期的数据,如果它找到两个日期的记录,则查询按预期工作,现在当没有 D- 记录时出现问题第 7 天,然后 $first 和 $last 具有相同的日期,因此它在 previousWeekCount 中也显示相同的数据。但是如果 D-7 天没有记录,我想插入 0 值。此外,我需要维护 $project 结构,因为它已发送到前端。我尝试了一些类似 $ifnull 的东西,也尝试了 $cond on日期,但没有任何建议或如何解决。以下是没有 D-7 日期记录的示例文档

{
    "_id" : ObjectId("5e73089d44eb7a50708167fc"),
    "orderedOnDate" : ISODate("2020-03-21T00:00:00.000Z"),
     "totalOrders" : [
            {      
                "orderCount" : 10,
                "code" : "#001",
            },
            {      
                "orderCount" : 46,
                "code" : "#002",
            },
    ],
}

现在如果没有第 7 天的记录,我可以根据代码显示 orderCount :0,我不想保存第 7 天的文档,只需要显示 0 值

【问题讨论】:

  • 当你在$group中使用$last时,你应该事先对文档进行排序,否则顺序不确定。也许$max$min 会是一个替代方案。
  • @ – Wernfried Domscheit $max,$min 好的,我在哪里匹配文档?之前你的意思是我应该在 $group 之前使用 $sort 对吗??
  • 是的,您必须在 $group 之前进行 $sort。 '$orderedOnDate' 可以使用 $max 或 $min,但我猜 '$totalOrders.orderCount' 需要正确排序
  • 你也可以用$or: [...]代替orderedOnDate: { $in: [ISODate("2020-03-21T00:00:00Z"), ISODate("2020-03-14T00:00:00Z")] }——但这更美观。
  • @- Wernfried Domscheit 但它会导致同样的问题我猜如果没有 D-7 天的记录它会在 previousWeekCount 中显示相同的 orderCount 但我希望你显示 0 值如果有没有第 7 天的记录 min 和 max 会有什么帮助?

标签: node.js mongodb mongoose aggregation-framework


【解决方案1】:

通常,如果没有提供示例输入数据和预期结果,我会拒绝回答。但是,此聚合应该为您提供解决方案的想法。通常每当我必须使用 Date 值时,我更喜欢使用 Moment.js 库。

db.collection.aggregate([
   {
      $match: {
         userId: ObjectId("5e7147ada3141a63a0dbc154"),
         orderedOnDate: { $in: [moment.utc().startOf('day').toDate(), moment.utc().startOf('day').subtract(7, 'days').toDate()] }
      }
   },
   { $sort: { orderedOnDate: 1 } },
   {
      $group: {
         _id: null,
         lastWeekOrders: { $first: "$$ROOT" },
         todayOrders: { $last: "$$ROOT" }
      }
   },
   {
      $set: {
         lastWeekOrders: {
            $cond: {
               if: { $eq: ["$lastWeekOrders.orderedOnDate", moment.utc().startOf('day').subtract(7, 'days').toDate()] },
               then: "$lastWeekOrders",
               else: {
                  orderedOnDate: moment.utc().startOf('day').subtract(7, 'days').toDate(),
                  totalOrders: [{ orderCount: 0 }]
               }
            }
         }
      }
   },
   {
      $set: {
         todayOrders: {
            $cond: {
               if: { $eq: ["$todayOrders.orderedOnDate", moment.utc().startOf('day').toDate()] },
               then: "$todayOrders",
               else: {
                  orderedOnDate: moment.utc().startOf('day').toDate(),
                  totalOrders: [{ orderCount: 0 }]
               }
            }
         }
      }
   },
])

【讨论】:

    猜你喜欢
    • 2021-11-24
    • 2022-10-31
    • 2013-07-24
    • 1970-01-01
    • 2019-09-08
    • 2018-02-20
    • 2014-03-31
    • 2020-10-28
    • 2017-06-24
    相关资源
    最近更新 更多