Estoy usando esta sintaxis para filtrar documentos

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

Antes de ejecutar esta consulta para encontrar todos los documentos, quiero ordenarlos por un orden específico que determinaré

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

Obtuve algún campo en la base de datos con cuatro valores opcionales, y quiero adjuntar el orden a cada valor (la clasificación debe aplicarse por eso). Digamos que los valores pueden ser:

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

El orden por el que quiero que se ordenen los documentos:

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

Y después de aplicar el ordenamiento, ejecute la consulta. El problema es que no pude encontrar nada sobre esto en línea, y lo único que probé (agregar con clasificación y condición) no funcionó. el código:

      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} }
]);
0
Noam Atishkin 26 abr. 2020 a las 18:31

2 respuestas

La mejor respuesta

Logré arreglarlo por un método diferente. Cuando inserto documentos en la base de datos, cada campo que quiero indexar tendrá otro campo que representará el índice del valor. (digamos que el nombre del campo es curso y sus valores son A, B, C, D; agregaré el campo llamado courseIndex y asignaré el índice por el valor: A = 4, B = 1, C = 2, D = 3)

Con esto puedo lograr ordenar con mis condiciones :)

0
Noam Atishkin 30 abr. 2020 a las 15:02

Parece un problema con los if/then/else s internos malformados. En realidad, falta algún operador $cond en el tercer y cuarto else. Debido a eso, obtiene un valor incorrecto para la propiedad order (un objeto con if/then/else en lugar de número).

Esta versión me funciona:

[
  {
    $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}}
]

Sin embargo, en este caso creo que el $switch operador podría ser mejor, especialmente si tiene más valores posibles (que solo esos 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}}
])
0
Jakub Janczyk 26 abr. 2020 a las 17:32