node.js - 过去 30 天内每天销售的订单数

标签 node.js mongodb mongoose

我需要帮助。我想修复这段代码。我已经尝试了几个小时了。我想要获取“每天销售的订单 - 默认日期范围:过去 30 天”。

这就是订单集合的样子

{
    status: 'BEING_PREPARED',
    option: 'DELIVERY',
    driver: null,
    staffComment: '',
    driverComment: null,
    paymentMethod: null,
    etd: null,
    ptd: null,
    deliveryFees: 0,
    discount: 0,
    voucherId: null,
    orderItems: [[Object], [Object], [Object]],
    subtotal: 24.849999999999998,
    branch: ObjectId("5c98a67a2061ed07b45100e1"),
    datetime: ISODate("2019-04-06T17:11:43.171Z"),
    number: 1347,
}

这就是我到目前为止所做的。

router.route('/api/ordes')
        .get(function(req, res) {

            var result = connection.db.collection("orders").aggregate([{
                    $match: {
                        "datetime": {
                            $lte: (new Date((new Date()).getTime() - (30 * 24 * 60 * 60 * 1000)))
                        }
                    }
                },
                {
                    "$group": {
                            _id: { 
                           "year":  { "$year": "$datetime" },
                           "month": { "$month": "$datetime" },
                           "day":   { "$dayOfMonth": "$datetime" }
                        },
                        totalValue: { $sum: "$subtotal" }
                    }
                }
            ]);
            result.toArray(function(err, doc) {
                console.log(doc);
                res.status(200).json(doc);

            });
        }); 

这是我得到的结果

[
    {
        "_id": {"year": 2019, "month": 7, "day": 2}, "totalValue": 3875.92
    },
    {
        "_id": {"year": 2019, "month": 6, "day": 30}, "totalValue": 9594.92
    },
    {

        "_id": {"year": 2019, "month": 6, "day": 29}, "totalValue": 8820.369999999999
    },
    {
        "_id": {"year": 2019, "month": 6, "day": 28}, "totalValue": 8881.76
    },
    {
        "_id": {"year": 2019, "month": 6, "day": 27}, "totalValue": 4286.66
    },
    {
        "_id": {"year": 2019, "month": 6, "day": 26}, "totalValue": 4716.66
    },
    {
        "_id": {"year": 2019, "month": 6, "day": 25}, "totalValue": 3093.82
    },
    {
        "_id": {"year": 2019, "month": 6, "day": 23}, "totalValue": 9905.26
    },
    {
        "_id": {"year": 2019, "month": 6, "day": 22}, "totalValue": 10492.32
    },
    {
        "_id": {"year": 2019, "month": 6, "day": 21}, "totalValue": 9261.52
    },
    {
        "_id": {"year": 2019, "month": 6, "day": 20}, "totalValue": 3794.98
    },
    {
        "_id": {"year": 2019, "month": 6, "day": 19}, "totalValue": 4191.64
    },
    {
        "_id": {"year": 2019, "month": 6, "day": 17}, "totalValue": 3749.33
    },
    {
        "_id": {"year": 2019, "month": 6, "day": 4}, "totalValue": 1915.72
    },
    {
        "_id": {"year": 2019, "month": 6, "day": 2}, "totalValue": 5884.91
    },
    {
        "_id": {"year": 2019, "month": 5, "day": 29}, "totalValue": 2784.5
    },
    {
        "_id": {"year": 2019, "month": 5, "day": 28}, "totalValue": 1986.87
    },
    {
        "_id": {"year": 2019, "month": 5, "day": 26}, "totalValue": 7209.74
    },
    {
        "_id": {"year": 2019, "month": 5, "day": 24}, "totalValue": 5398.99
    },
    {
        "_id": {"year": 2019, "month": 7, "day": 4}, "totalValue": 4256.6
    },
    {
        "_id": {"year": 2019, "month": 5, "day": 23}, "totalValue": 2365.48
    },
    {
        "_id": {"year": 2019, "month": 5, "day": 22}, "totalValue": 2452.8199999999997
    }
]

最佳答案

保留原有结构,使用$$ROOT保存订单数据的变量:

connection.db.collection("orders").aggregate([
    {
        $match: {
            "datetime": {
                $lte: (new Date((new Date()).getTime() - (30 * 24 * 60 * 60 * 1000)))
            }
        }
    },
    {
        "$group": {
            _id: {
                "year": {"$year": "$datetime"},
                "month": {"$month": "$datetime"},
                "day": {"$dayOfMonth": "$datetime"}
            },
            totalValue: {$sum: "$subtotal"},
            orders: {$push: "$$ROOT"}
        }
    }
]);

编辑:

您可以使用打击聚合来获得所需的结果,因为我们无法知道数据库中的最后日期,所以我们必须首先对所有集合进行分组。

我个人建议您不要这样做,而是将其分为两个步骤,首先查询以查找最大日期。那么你可以使用

{
        $match: {
            "datetime": {
                $lte: (new Date((maxDateFromCollection.getTime() - (30 * 24 * 60 * 60 * 1000)))
            }
        }
    }

为了匹配,当规模变大时,效率会提高很多。

connection.db.collection("orders").aggregate([
    {
        "$group": {
            _id: {
                "year": {"$year": "$datetime"},
                "month": {"$month": "$datetime"},
                "day": {"$dayOfMonth": "$datetime"}
            },
            totalValue: {$sum: "$subtotal"},
        }
    },
    {
        $sort: {
            "_id.year": -1,
            "_id.month": -1,
            "_id.day": -1,
        }
    },
    {
        $limit: 30
    },
    // next steps are only necessary if days could be missing and we have less than 30 results.
    {
        $group: {
            _id: null,
            orders: {$push: "$$ROOT"},
            maxDate: {$first: "$_id"}
        }
    },
    {
        $unwind: "$orders"
    },
    {
        $match: {
            $or: [
                {
                    $and: [ // same month if its months with 30 or less days. or day greater than 1.
                        {
                            $or: [
                                {
                                    "orders._id.day": {$gt: 1},
                                },
                                {
                                    "orders._id.month": {$in: [2, 4, 6, 8, 10, 12]}
                                }
                            ]
                        },
                        {
                            $expr: {
                                $eq: ["$orders._id.year", "$maxDate.year"]
                            }
                        },
                        {
                            $expr: {
                                $eq: ["$orders._id.month", "$maxDate.month"]
                            }

                        }
                    ]
                },
                {
                    $and: [ // if day is 1 than no 31
                        {
                            $expr: {
                                $eq: [
                                    "$orders._id.year", "$maxDate.year"]
                            }
                        },
                        {
                            $expr: {
                                $eq: [
                                    "$orders._id.month", "$maxDate.month"]
                            }
                        },
                        {
                            "orders._id.day": {$ne: 31}
                        }
                    ]
                },
                {   // days from previous month
                    $and: [
                        {
                            "maxDate.month": {$in: [5, 7, 10, 12]}
                        },
                        {
                            $expr: {
                                $eq: [
                                    "$orders._id.year", "$maxDate.year"]
                            }
                        },
                        {
                            $expr: {
                                $eq: [
                                    "$orders._id.month", {$subtract: ["$maxDate.month", 1]}
                                ]
                            }
                        },
                        {
                            $expr: {
                                $gt: [
                                    "$orders._id.day", "$maxDate.day"
                                ]
                            }
                        }
                    ]
                },
                {   // days from previous month
                    $and: [
                        {
                            "maxDate.month": {$in: [2, 4, 6, 8, 9, 11]}
                        },
                        {
                            $expr: {
                                $eq: [
                                    "$orders._id.year", "$maxDate.year"
                                ]
                            }
                        },
                        {
                            $expr: {
                                $eq: [
                                    "$orders._id.month", {$subtract: ["$maxDate.month", 1]}
                                ]
                            }
                        },
                        {
                            $expr: {
                                $gt: [
                                    "$orders._id.day", {$add: ["$maxDate.day", 1]}
                                ]
                            }
                        }
                    ]
                },
                {   // days from previous month
                    $and: [
                        {
                            "maxDate.month": 3
                        },
                        {
                            $expr: {
                                $eq: [
                                    "$orders._id.year", "$maxDate.year"
                                ]
                            }
                        },
                        {
                            $expr: {
                                $eq: [
                                    "$orders._id.month", {$subtract: ["$maxDate.month", 1]}
                                ]
                            }
                        },
                        {
                            $expr: {
                                $gt: [
                                    "$orders._id.day", {$subtract: ["$maxDate.day", 2]}
                                ]
                            }
                        }
                    ]
                },
                {   // days from previous month
                    $and: [
                        {
                            "maxDate.month": 1
                        },
                        {
                            "orders._id.month": 12
                        },
                        {
                            $expr: {
                                $eq: [
                                    "$orders._id.year", {$subtract: ["$maxDate.year", 1]}
                                ]
                            }
                        },
                        {
                            $expr: {
                                $gt: [
                                    "$orders._id.day", {$add: ["$maxDate.day", 1]}
                                ]
                            }
                        }
                    ]
                },
            ]
        }
    },
    {
        $replaceRoot: {
            newRoot: "$orders"

        }
    }
])

关于node.js - 过去 30 天内每天销售的订单数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60172036/

相关文章:

node.js - $inc 忽略 Mongoose

node.js - 模型相互引用错误 : circular dependencies problem

mysql - 临时表不存在错误

javascript - Javascript 可以原生连接到 MongoDB 吗?

python - 将 mongodb 返回对象转换为字典

javascript - Node : TypeError: Cannot read property 'sort' of undefined when doing a findOneAndUpdate() inside of a find()

javascript - 无法使用 upsert 删除键

node.js - 如何获取redis中的所有用户

node.js - 带有灰尘的 mongo 中的服务器端渲染

javascript - 元素在 Selenium webdriver 点不可点击