расширенная сортировка mongoDb по запросу агрегации - PullRequest
0 голосов
/ 19 марта 2020

Я пытаюсь написать запрос на mongoDb, чтобы сгруппировать данные по определенному полю (storeId). Каждая группа будет иметь несколько записей для одного и того же storeId. Мне нужно, чтобы записи в каждой группе были упорядочены по полю (timeStamp). Еще лучшим решением было бы после сортировки записей в каждой группе выбрать только первую запись, чтобы в каждой группе была только одна запись. Это то, что я пытался:

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" или "data"

Любая помощь будет оценена. Я заранее прошу прощения, если это считается легким, но я новичок в мире информационных технологий, а также пришел с SQL сервера.

Ответы [ 2 ]

1 голос
/ 19 марта 2020

Если вам нужна только первая запись, вы можете попробовать это:

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, поэтому вы можете добавить их.

0 голосов
/ 19 марта 2020

После слишком большого количества тестов и прочтения документации я понял, что mon go сортировка немного отличается от мира 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"}}}
        }   
    ]) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...