Сортировка нескольких условий MongoDB - PullRequest
0 голосов
/ 08 мая 2018

У меня есть коллекция пользователя, и это следующие документы:

{ "_id": 1, "name": "A", "online": 1, "like": 10, "score": 1 },
{ "_id": 2, "name": "B", "online": 0, "like": 9, "score": 0 },
{ "_id": 3, "name": "C", "online": 0, "like": 8, "score": 1 },
{ "_id": 4, "name": "D", "online": 1, "like": 8, "score": 0 },
{ "_id": 5, "name": "E", "online": 1, "like": 7, "score": 1 },
{ "_id": 6, "name": "F", "online": 0, "like": 10, "score": 1 },
{ "_id": 7, "name": "G", "online": 0, "like": 5, "score": 0 },
{ "_id": 8, "name": "H", "online": 0, "like": 13, "score": 0 }
{ "_id": 9, "name": "I", "online": 0, "like": 6, "score": 0 }

Я хочу показать список пользователей с некоторыми из критериев и порядка размещения с некоторыми условиями, онлайн-пользователями и наиболее понравившимися в верхней части списка, после того, как онлайн-список пользователей показывает автономных пользователей с наиболее набранными и наиболее понравившимися. Следующие правила:

  1. Если online равно 1, необходимо выполнить сортировку по убыванию like.
  2. Если online равно 0 и score равно 1, необходимо выполнить сортировку по убыванию score.
  3. Если online равно 0 и score равно 0, необходимо выполнить сортировку по убыванию like.

Итак, результат может быть таким:

{ "_id": 1, "name": "A", "online": 1, "like": 10, "score": 1 },
{ "_id": 4, "name": "D", "online": 1, "like": 8, "score": 0 },
{ "_id": 5, "name": "E", "online": 1, "like": 7, "score": 1 },
{ "_id": 6, "name": "F", "online": 0, "like": 10, "score": 1 },
{ "_id": 3, "name": "C", "online": 0, "like": 8, "score": 1 },
{ "_id": 8, "name": "H", "online": 0, "like": 13, "score": 0 }
{ "_id": 2, "name": "B", "online": 0, "like": 9, "score": 0 },
{ "_id": 9, "name": "I", "online": 0, "like": 6, "score": 0 },
{ "_id": 7, "name": "G", "online": 0, "like": 5, "score": 0 }

Я закончил до пункта 2, мой запрос следующий:

db.users.aggregate([
{
   $project :
       {
           "id" : 1,
           "name" : 1,
           "online: 1,
           "like" : 1,
           "score" : 1,
           "sort" : {
               $cond:
                   {
                       "if" :
                           {
                               $eq : ["$online", true]
                           },
                       "then" : "$like",
                       "else" : "$score"
                   }
           }
       }
},
{
   $sort :
       {
           "online" : -1,
           "sort" : -1,
           "id" : 1
       }
},
{
   $skip : 0
},
{
   $limit : 9
}
])

Но у меня текущий результат следующий:

{ "_id": 1, "name": "A", "online": 1, "like": 10, "score": 1 },
{ "_id": 4, "name": "D", "online": 1, "like": 8, "score": 0 },
{ "_id": 5, "name": "E", "online": 1, "like": 7, "score": 1 },
{ "_id": 6, "name": "F", "online": 0, "like": 10, "score": 1 },
{ "_id": 3, "name": "C", "online": 0, "like": 8, "score": 1 },
{ "_id": 2, "name": "B", "online": 0, "like": 9, "score": 0 },
{ "_id": 7, "name": "G", "online": 0, "like": 5, "score": 0 },
{ "_id": 8, "name": "H", "online": 0, "like": 13, "score": 0 }
{ "_id": 9, "name": "I", "online": 0, "like": 6, "score": 0 },

Вы можете видеть, исходя из пункта 3, экземпляр { "_id": 8, "name": "H", "online": 0, "like": 13, "score": 0 } должен быть сверху с score, равным 0

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Пожалуйста, проверьте ниже запрос:

db.getCollection('yourTable').aggregate([
{
   $project :
       {
           "id" : 1,
           "name" : 1,
           "online": 1,
           "like" : 1,
           "score" : 1,
           onlineSortLike: {
            $cond: {
              if: { $and: [{ $eq: ['$online',1 ] }] },
              then: '$like', 
              else: 0,
            },
          },
          sortOfflineScore: {
            $cond: {
              if: { $and: [{ $eq: ['$online',0] }] },
              then: '$score', 
              else: 0,
            },
          },
          sortOfflineScoreLike: {
            $cond: {
              if: { $and: [{ $eq: ['$online', 0] }] },
              then: '$like', 
              else: 0,
            },
          },


       }
},
{
   $sort :
       {
           "online" : -1,
           "onlineSortLike" : -1,
           "sortOfflineScore" : -1,
           "sortOfflineScoreLike" : -1
       }
},
{
   $skip : 0
},
{
   $limit : 9
}
])
0 голосов
/ 08 мая 2018

Сначала создайте дополнительный вызов столбца point со значением (1 - online)*score

После сортировки данных по:

  1. online desc
  2. point desc (онлайн = 1 point всегда 0, онлайн 0 point score)
  3. like desc

Вы можете использовать этот запрос

    db.yourtable.aggregate(
            [ 
                { $project:{
                    "id" : 1,
                    "name" : 1,
                    "online": 1,
                    "like" : 1,
                    "score" : 1,
                    point: { $multiply: [ 
                                    {$subtract: [1,"$online"]}                      
                                    , "$score"
                            ]}

                    }
                }
                ,{ $sort : { online: -1, point : -1, like : -1 } }
            ]
        );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...