es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Proyección de mongoose para filtrar una lista que no funciona, pero la opción nativa sí.

Estoy tratando de usar la siguiente consulta de búsqueda para encontrar una lista de objetos relacionados con un objeto “work” con un ID específico, y luego devolver todos los elementos “form” que no están configurados como inactivos (active = false).

Esto funciona perfectamente usando la terminal de Mongo localmente, o probándolo en mongoplayground. Pero no logro entender cómo hacer que mongoose funcione correctamente y devuelva los resultados que espero, siempre obtengo una matriz vacía.

No entiendo por qué funcionaría perfectamente de forma nativa pero no a través de mongoose. Debe haber algún tipo de problema o peculiaridad que no encuentro en la documentación. Mi versión de MongoDB es 5.0.5 y mi versión de mongoose es 6.1.5.

Consulta de búsqueda de Mongo que estoy intentando usar:

db.objects.find({
“work”: ObjectId(“61d50a22eed3f421dc33a220”)
},
{
“form”: {
“$filter”: {
“input”: “$form”,
“as”: “form”,
“cond”: {
“$ne”: [
“$$form.active”,
false
]
}
}
}
})

Código de Mongoose con proyección (no funciona, devuelve []):
export const getWIObjects = async (workID: string) => {
const objs = await ObjectModel.find({
work: new mongoose.Types.ObjectId(workID),
}).select({
form: {
$filter: {
input: “$form”,
as: “form”,
cond: {
$ne: [“$$form.active”, false],
},
},
},
});
return objs;
};

Código de Mongoose SIN proyección (devuelve datos pero incluirá campos inactivos):
export const getWIObjects = async (workID: string) => {
const objs = await ObjectModel.find({
work: new mongoose.Types.ObjectId(workID),
});
return objs;
};

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para lograr el resultado deseado de encontrar una lista de objetos relacionados con un objeto “work” con un ID específico, y devolver todos los elementos “form” que no estén configurados como inactivos (active = false) utilizando Mongoose, se deben realizar varios cambios en el código:

    1. El operador $filter debe estar dentro del operador $project, para proyectar solo los campos deseados.
    2. El operador $filter debe hacer referencia al campo “form” utilizando la notación de punto.
    3. El operador $ne debe cambiarse por $eq, ya que queremos filtrar solo los campos activos.
    4. El operador $eq debe recibir un valor booleano de true, ya que queremos que coincida solo con los campos activos.

    Aquí está el código actualizado:

    export const getWIObjects = async (workID: string) => {
      const objs = await ObjectModel.aggregate([
        {
          $match: {
            work: new mongoose.Types.ObjectId(workID),
          },
        },
        {
          $project: {
            form: {
              $filter: {
                input: "$form",
                as: "form",
                cond: {
                  $eq: ["$$form.active", true],
                },
              },
            },
          },
        },
      ]);
      return objs;
    };
    

    Este código utiliza el método aggregate de Mongoose para realizar la operación de filtrado, lo que nos permite usar el operador $project para seleccionar solo los campos deseados. El operador $filter se utiliza para filtrar el campo “form” y el operador $eq se utiliza para seleccionar solo los campos activos.

    Este código debería devolver los resultados deseados.

Comments are closed.