mongoDB сортировать по двум полям - PullRequest
2 голосов
/ 07 апреля 2020

У меня есть документ mongodb, как показано ниже:

 {

        "match_key" : 44801,
        "total_points" : 10.00,


    },
    {
        "match_key" : 44901,
        "total_points" : 8.00,
    },
   {
        "match_key" : 44901,
        "total_points" : 7.00,
    },

   {
        "match_key" : 44901,
        "total_points" : 11.00,
    },
    {

    "match_key" : 44801,
    "total_points" : 7.00,


}

Я хочу отсортировать вышеупомянутые документы, но хочу сохранить документы с одним и тем же ключом match_key вместе.

Фактический результат:

 {
        "match_key" : 44901,
        "total_points" : 11.00,
    }
,
 {

        "match_key" : 44801,
        "total_points" : 10.00,


    },
{
        "match_key" : 44901,
        "total_points" : 8.00,
    },

{

    "match_key" : 44801,
    "total_points" : 7.00,


}

 {
        "match_key" : 44901,
        "total_points" : 6.00,
    },

Но вы видите, что одни и те же ключи соответствия не вместе.

Ожидаемый результат:

{
        "match_key" : 44901,
        "total_points" : 11.00,
    },
{
        "match_key" : 44901,
        "total_points" : 8.00,
    },
{
        "match_key" : 44901,
        "total_points" : 7.00,
    },
{

        "match_key" : 44801,
        "total_points" : 10.00,


    },
{

        "match_key" : 44801,
        "total_points" : 6.00,


    },

Так, что документы с ключом same_match находятся в порядке убывания.

Вот что я пытался сделать:

 db.collection.aggregate(
    [
      { $match: { match_key:{$in:[44801,45910]}}},
      { $sort: {total_points:1,match_key:1} }
    ]
 )

Это некоторый sql эквивалент вопрос, который я пытаюсь задать - Сортировать по самому последнему, но хранить вместе по другому столбцу идентификаторов

Мой основной мотив здесь - сортировать документы и хранить документы с одним и тем же match_key вместе, но в порядке / **

1 Ответ

1 голос
/ 07 апреля 2020

Вам нужно разделить это $sort на два этапа, как показано ниже:

db.collection.aggregate([
  {
    $match: {
      match_key: {
        $in: [
          44801,
          45910
        ]
      }
    }
  },
  {
    $sort: {
      total_points: -1
    }
  },
  {
    $sort: {
      match_key: -1
    }
  }
])

Тест: MongoDB-Playground

Примечание: Поскольку на первом этапе $match у нас все хорошо, мы должны хорошо выполнить сортировку, но даже если нам нужно выполнить сортировку дважды, постарайтесь, чтобы ваш набор данных был как можно ниже, Вам необходимо иметь два индекса одного поля на двух ваших полях total_points & match_key.

Проблема: Поэтому, когда вы делаете это: { $sort: {total_points:-1,match_key:1} } ваш запрос сначала сортируется по полю total_points :1, и если он находит два документа с одинаковым значением total_points, он go до match_key:1 отсортирует эти два документа, чтобы сохранить их в порядке.

Пример проблемы: Используя составную сортировку, как описано выше, вы получите результат ниже

  {
    "_id": ObjectId("5a934e000102030405000002"),
    "match_key": 44801,
    "total_points": 10
  },
  {
    "_id": ObjectId("5a934e000102030405000003"),
    "match_key": 45910,
    "total_points": 10
  },
  {
    "_id": ObjectId("5a934e000102030405000005"),
    "match_key": 44801,
    "total_points": 7
  }

Если вы видите, total_points отсортированы по порядку, с первым приоритетом на total_points, и так как есть в двух документах с "total_points": 10 он получает второй приоритет match_key. В любом случае, если вы хотите сортировать как 11->10->7, вам нужно использовать нисходящий механизм с -1, но не с 1 (что по возрастанию).

...