пн goose сортировка документов по заданным c значениям из документа - PullRequest
0 голосов
/ 26 апреля 2020

Я использую этот синтаксис для фильтрации документов

const query = Model.find();
const filters = req.body;
if(filters.someValue){
    query.find().where('someValue').eq(filters.someValie);
}
...(imagine 40 more)

, прежде чем выполнить этот запрос, чтобы найти все документы, я хочу отсортировать его по указанному c порядку, который я определю

if(filters.sort){
    here the sort need to be applied - before execution.
}

Я получил некоторое поле в БД с четырьмя необязательными значениями, и я хочу прикрепить порядок к каждому значению (сортировка должна быть применена этим). Допустим, значения могут быть:

"A", "B", "C", "D"

порядок, в котором я хочу отсортировать документы:

{value:"A",order:3}, {value:"B", order:2}, {value:"C", order:4}, {value:"D", order:1}

и после применения сортировки - выполнить запрос. проблема в том, что я не мог ничего найти об этом в Интернете, и единственное, что я попробовал (Агрегировать с сортировкой и состоянием) - не сработало. код:

      SomeModel.aggregate([
    { "$project" : {
      "document": "$$ROOT",
        "order" : {
            "$cond" : {
                if : { "$eq" : ["$someField", "D"] }, then : 1,
                else  : { "$cond" : {
                    "if" : { "$eq" : ["$someField", "B"] }, then : 2, 
                    else  : { "if" : { "$eq" : ["$someField", "A"]}, then: 3, 
                    else : { "if" : { "$eq" : ["$someField", "C"]}, then: 4
                        }
                      }
                    }
                }
            }
        }
    }}, 
    {"$sort" : {"order" : 1} }
]);

Ответы [ 2 ]

0 голосов
/ 30 апреля 2020

Мне удалось это исправить другим способом. Когда я вставляю документы в БД - каждое поле, которое я хочу проиндексировать, будет иметь другое поле, которое будет представлять индекс значения. (допустим, имя поля - курс, а его значения - A, B, C, D - я добавлю поле с именем courseIndex и сопоставлю индекс по значению - A = 4, B = 1, C = 2, D = 3).

С этим я могу добиться сортировки с моими условиями :)

0 голосов
/ 26 апреля 2020

Это похоже на проблему с искаженными внутренними if/then/else с. На самом деле вам не хватает оператора $cond в третьем и четвертом else. Из-за этого вы получаете неправильное значение для свойства order (объект с if/then/else вместо числа).

Эта версия работает для меня:

[
  {
    $project: {
      'document': '$$ROOT',
      order: {
        $cond: {
          if: {'$eq': ['$someField', 'D']}, then: 1,
          else: {
            '$cond': {
              'if': {'$eq': ['$someField', 'B']}, then: 2,
              else: {
                '$cond': {
                  'if': {'$eq': ['$someField', 'A']}, then: 3,
                  else: {
                    '$cond': {'if': {'$eq': ['$someField', 'C']}, then: 4, else: 5}
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  {$sort: {'order': 1}}
]

Однако в этом case, я думаю, оператор $switch может быть лучше, особенно если у вас есть больше возможных значений (чем только эти 4).

aggregate([
  {
    $project: {
      'document': '$$ROOT',
      order: {
        $switch: {
          branches: [
            {case: {'$eq': ['$name', 'D']}, then: 1},
            {case: {'$eq': ['$name', 'B']}, then: 2},
            {case: {'$eq': ['$name', 'A']}, then: 3},
            {case: {'$eq': ['$name', 'C']}, then: 4},
          ],
          default: null
        }
      }
    }
  },
  {$sort: {'order': 1}}
])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...