findOne () devuelve todo el documento, en lugar de un único objeto

votos
0

Estoy tratando de consultar este conjunto de datos mediante findOne():

{
    _id: {
        $oid: 5c1a4ba1482bf501ed20ae4b
    },
    wardrobe: {
        items: [
            {
                type: T-shirt,
                colour: Gray,
                material: Wool,
                brand: Filson,
                _id: 5c1a4b7d482bf501ed20ae4a
            },
            {
                type: T-shirt,
                colour: White,
                material: Acrylic,
                brand: H&M,
                _id: 5c1a4b7d482bf501ed20ae4a
            }
        ]
    },
    tokens: [],
    email: another@new.email,
    password: $2a$10$quEXGjbEMX.3ERdjPabIIuMIKu3zngHDl26tgRcCiIDBItSnC5jda,
    createdAt: {
        $date: 2018-12-19T13:46:09.365Z
    },
    updatedAt: {
        $date: 2018-12-19T13:47:30.123Z
    },
    __v: 2
}

Quiero devolver un solo objeto a partir de la itemsmatriz utilizando _Idcomo filtro. Esta es la forma en que estoy haciendo lo siguiente:

exports.deleteItem = (req, res, next) => {
    User.findOne({ 'wardrobe.items': { $elemMatch: { _id: 5c1a4b7d482bf501ed20ae4a,} } }, (err, item) => {
    console.log(item);
    if (err) {
        return console.log(error:  + err);
        }
        res.redirect('/wardrobe');      
    });
  };

Sin embargo, console.log(item)devuelve el conjunto de documentos de este modo:

{ wardrobe: { items: [ [Object], [Object] ] },
  tokens: [],
  _id: 5c1a4ba1482bf501ed20ae4b,
  email: 'another@new.email',
  password:
   '$2a$10$quEXGjbEMX.3ERdjPabIIuMIKu3zngHDl26tgRcCiIDBItSnC5jda',
  createdAt: 2018-12-19T13:46:09.365Z,
  updatedAt: 2018-12-19T13:47:30.123Z,
  __v: 2 }

Quiero utilizar este tiempo para eliminar elementos individuales, por lo que necesito para filtrar al objeto sencillo del subdocumento.

Publicado el 19/12/2018 a las 14:20
fuente por usuario
En otros idiomas...                            


1 respuestas

votos
1

En cuanto a su pregunta: MongoDB siempre devuelve el objeto completo coincidan con su consulta, a menos que se agrega una Especificación de proyección que se deben devolver los campos. Si realmente quiere sólo para devolver un objeto anidado, se puede utilizar la tubería de agregación con el operador $ replaceRoot como esto:

User.aggregate([
 // you can directly query for array fields instead of $elemMatching them
 { $match: { 'wardrobe.items._id': "5c1a4b7d482bf501ed20ae4a"}}},
 // this "lifts" the fields wardrobe up and makes it the new root
 { $replaceRoot: {newRoot: '$wardrobe'}
 // this "splits" the array into separate objects
 { $unwind: '$items'},
 // this'll remove all unwanted elements
 { $match: { 'items._id': "5c1a4b7d482bf501ed20ae4a" },
 },
])

Esto debería devolver sólo los elementos deseados.

Una nota sin embargo: Si va a eliminar elementos de las matrices de todos modos, prefiero sugerir que echar un vistazo a la operación de $ tirón, que puede eliminar un elemento de una matriz si coincide con una determinada condición:

https://docs.mongodb.com/manual/reference/operator/update/pull/

User.update(
  { 'wardrobe.items._id': "5c1a4b7d482bf501ed20ae4a"},
  { $pull: { 'wardrobe.items': {_id: "5c1a4b7d482bf501ed20ae4a"}},
  { multi: true }
)
Respondida el 19/12/2018 a las 15:44
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more