findOne () retourne document entier, au lieu d'un seul objet

voix
0

Je suis en train d'interroger cet ensemble de données à l' aide 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
}

Je veux retourner un seul objet à partir du itemstableau en utilisant _Idcomme filtre. Voilà comment je fais ça:

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');      
    });
  };

Cependant, console.log(item)retourne l'ensemble comme document afin:

{ 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 }

Je veux utiliser ce terme pour supprimer des éléments simples, donc je dois filtrer à l'objet unique de la sous-document.

Créé 19/12/2018 à 14:20
source utilisateur
Dans d'autres langues...                            


1 réponses

voix
1

En ce qui concerne votre question: MongoDB renvoie toujours l'objet complet correspondant à votre requête, sauf si vous ajoutez une spécification de projection quels champs doivent être renvoyés. Si vous voulez vraiment revenir seulement un objet imbriqué, vous pouvez utiliser le pipeline d'agrégation avec l'opérateur de replaceRoot $ comme ceci:

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" },
 },
])

Cela devrait revenir uniquement les éléments recherchés.

Une note cependant: Si vous envisagez de supprimer des éléments de tableaux de toute façon, je préfère vous suggère de jeter un oeil à l'opération de traction $, ce qui peut supprimer un élément d'un tableau si elle correspond à une certaine condition:

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

User.update(
  { 'wardrobe.items._id': "5c1a4b7d482bf501ed20ae4a"},
  { $pull: { 'wardrobe.items': {_id: "5c1a4b7d482bf501ed20ae4a"}},
  { multi: true }
)
Créé 19/12/2018 à 15:44
source utilisateur

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