Как отсортировать внутренние элементы массива, сохраняя различную сортировку для внешних документов?

У меня есть коллекция документов, каждый из которых имеет встроенный массив. Мне нужно, чтобы элементы каждого массива были отсортированы внутри себя, в то время как содержащиеся в них документы должны оставаться в таком порядке, как они есть.

В качестве примера, взяв данные из этого аналогичного вопроса о сортировке:

[
    {
        name: 'item1',
        slots: [
            { date : ISODate("2013-01-18T23:00:00Z") },
            { date : ISODate("2013-02-05T23:00:00Z") },
            { date : ISODate("2013-03-24T23:00:00Z") },
        ]
    },
    {
        name: 'item2',
        slots: [
            { date : ISODate("2013-01-12T23:00:00Z") },
            { date : ISODate("2013-01-03T23:00:00Z") },
            { date : ISODate("2013-03-04T23:00:00Z") },
        ]
    },
    {
        name: 'item3',
        slots: [
            { date : ISODate("2013-03-14T23:00:00Z") },
            { date : ISODate("2013-02-18T23:00:00Z") },
            { date : ISODate("2013-03-07T23:00:00Z") },
        ]
    }
]

Мой ожидаемый результат немного отличается:

[
    {
        name: 'item3',
        slots: [
            { date : ISODate("2013-02-18T23:00:00Z") },
            { date : ISODate("2013-03-07T23:00:00Z") },
            { date : ISODate("2013-03-14T23:00:00Z") },
        ]
    },
    {
        name: 'item2',
        slots: [
            { date : ISODate("2013-01-03T23:00:00Z") },
            { date : ISODate("2013-01-12T23:00:00Z") },
            { date : ISODate("2013-03-04T23:00:00Z") },
        ]
    },
    {
        name: 'item1',
        slots: [
            { date : ISODate("2013-01-18T23:00:00Z") },
            { date : ISODate("2013-02-05T23:00:00Z") },
            { date : ISODate("2013-03-24T23:00:00Z") },
        ]
    }
]

Как я могу добиться этого в MongoDB 3.6? Я хотел бы использовать конвейер агрегации, если это возможно.

Я пока не очень старался, так как единственная сцена, которая, я думаю, подойдет для этого, - это $sort, но, как указано в документации, он будет сортировать внешнюю коллекцию.

1 ответ

Решение

Вы можете использовать приведенный ниже агрегационный запрос.

$unwind slots массив с последующей сортировкой документов по дате и времени $group обратно на _id чтобы получить отсортированный массив.

$sort на name desc для сортировки документов.

db.col.aggregate([
  {"$unwind":"$slots"},
  {"$sort":{"slots.date":1}},
  {"$group":{"_id":"$_id","name":{"$first":"$name"},"slots":{"$push":"$slots"}}},
  {"$sort":{"name":-1}},
])
Другие вопросы по тегам