【问题标题】:mongoDb advanced sorting on aggregation querymongoDb 对聚合查询的高级排序
【发布时间】:2020-03-19 18:09:58
【问题描述】:

我正在尝试在 mongoDb 上编写一个查询,以按特定字段 (storeId) 对数据进行分组。每个组将有多个相同 storeId 的记录。我需要按字段(时间戳)对每个组的记录进行排序。一个更好的解决方案是在对每个组的记录进行排序之后,只选择第一个记录,这样每个组只有一个记录。 这是我尝试过的:

const result = await deliverydays.aggregate([
    {
        $match: {
            "storeId": { $in: storeIds },
            "eci.openTimeStamp": { $ne: null },
            "eci.dayStatus": "OPEN"
        }

    },
    {
        $group: {
            _id: "$storeId",
            data: {
                $push: { openTimeStamp: "$eci.openTimeStamp", storeId: "$storeId" }
            },
            $sort: { openTimeStamp: 1 }
        }
    }
])

它报错“字段 '$sort' 必须是一个累加器对象” 我也试过这个:

const result = await deliverydays.aggregate([
    {
        $match: {
            storeId: { $in: storeIds },
            "eci.openTimeStamp": { $ne: null },
            "eci.dayStatus": "OPEN"
        }

    },
    {
        $group: {
            _id: "$storeId",
            data: {
                $push: { openTimeStamp: "$eci.openTimeStamp", storeId: "$storeId" }
            }
        }
    },
    {
        $sort: { openTimeStamp: 1 }
    }
])

但还是不行。我意识到第二个结构只有当我想按“_id”或“数据”排序时

任何帮助将不胜感激。如果这被认为很容易,我提前道歉,但我是 IT 界的新手,而且我来自 SQL Server。

【问题讨论】:

  • 你应该使用$sort: { "data.openTimeStamp": 1 }
  • 它似乎不起作用。

标签: mongodb mongodb-query


【解决方案1】:

如果你只需要第一条记录,你可以试试这个:

const result = await deliverydays.aggregate([
{
    $sort: {
        "openTimeStamp": -1
    }
},
{
    $group: {
        _id: "$storeId",
        data: {
            $first: {
                'openTimeStamp': '$openTimeStamp',
                'storeId': '$storeId'
            }
        }
    }
}])

如果需要返回整条记录,可以试试$$ROOT

const result = await deliverydays.aggregate([
{
    $sort: {
        "openTimeStamp": -1
    }
},
{
    $group: {
        _id: "$storeId",
        data: {
            $first: '$$ROOT'
        }
    }
}])

我没有包含您的 match 查询和 eci 前缀,因此您可以添加它们。

【讨论】:

  • 优秀的答案,干净,它完全符合问题的要求。
【解决方案2】:

经过太多的测试和阅读文档后,我意识到 mongo 的排序与 SQL 世界有点不同。 您需要在对记录进行分组之前对其进行排序。如果将来有人需要,这就是最终查询的样子:

        const result = await deliverydays.aggregate([
        {
            $match:{storeId:{$in:storeIds}, 
            "eci.openTimeStamp":{$ne:null}, 
            "eci.dayStatus": "OPEN"}

        },
        {
            $sort:{"eci.openTimeStamp": -1}
        },
        {
            $group:{_id: "$storeId", data:{$push:{openTimeStamp:"$eci.openTimeStamp", storeId: "$storeId"}}}
        }   
    ]) 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-12
    • 2021-03-09
    • 2016-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-19
    • 1970-01-01
    相关资源
    最近更新 更多