web-dev-qa-db-fra.com

Conversion de documents Mongoose en json

J'ai retourné des documents sur la mangouste en json de cette façon:

UserModel.find({}, function (err, users) {
    return res.end(JSON.stringify(users));
}

Cependant, l'utilisateur .__ proto__ a également été renvoyé. Comment puis-je revenir sans elle? J'ai essayé ça mais ça n'a pas marché:

UserModel.find({}, function (err, users) {
    return res.end(users.toJSON());    // has no method 'toJSON'
}
60
Trantor Liu

Vous pouvez aussi essayer les mongoosejs lean () :

UserModel.find().lean().exec(function (err, users) {
    return res.end(JSON.stringify(users));
}
124
ecdeveloper

Réponse tardive, mais vous pouvez également essayer ceci lors de la définition de votre schéma.

/**
 * toJSON implementation
 */
schema.options.toJSON = {
    transform: function(doc, ret, options) {
        ret.id = ret._id;
        delete ret._id;
        delete ret.__v;
        return ret;
    }
};

Notez que ret est l'objet géré par JSON et qu'il ne s'agit pas d'une instance du modèle mangouste. Vous l'exploiterez directement sur les objets en hachage, sans les accesseurs.

Et alors:

Model
    .findById(modelId)
    .exec(function (dbErr, modelDoc){
         if(dbErr) return handleErr(dbErr);

         return res.send(modelDoc.toJSON(), 200);
     });

Edit: Feb 2015

Comme je n'ai pas fourni de solution aux méthodes toJSON (ou toObject) manquantes, je vais expliquer la différence entre mon exemple d'utilisation et l'exemple d'utilisation de OP.

OP:

UserModel
    .find({}) // will get all users
    .exec(function(err, users) {
        // supposing that we don't have an error
        // and we had users in our collection,
        // the users variable here is an array
        // of mongoose instances;

        // wrong usage (from OP's example)
        // return res.end(users.toJSON()); // has no method toJSON

        // correct usage
        // to apply the toJSON transformation on instances, you have to
        // iterate through the users array

        var transformedUsers = users.map(function(user) {
            return user.toJSON();
        });

        // finish the request
        res.end(transformedUsers);
    });

Mon exemple:

UserModel
    .findById(someId) // will get a single user
    .exec(function(err, user) {
        // handle the error, if any
        if(err) return handleError(err);

        if(null !== user) {
            // user might be null if no user matched
            // the given id (someId)

            // the toJSON method is available here,
            // since the user variable here is a 
            // mongoose model instance
            return res.end(user.toJSON());
        }
    });
46
eAbi

Tout d’abord, essayez toObject() au lieu de toJSON() peut-être?

Deuxièmement, vous aurez besoin de l'appeler sur les documents eux-mêmes et non sur le tableau, alors essayez peut-être quelque chose de plus gênant comme ceci:

var flatUsers = users.map(function() {
  return user.toObject();
})
return res.end(JSON.stringify(flatUsers));

C'est une supposition, mais j'espère que ça aide

24
Jamund Ferguson
model.find({Branch:branch},function (err, docs){
  if (err) res.send(err)

  res.send(JSON.parse(JSON.stringify(docs)))
});
12
Fabio Guerra

J'ai découvert que j'avais commis une erreur. Il n'est pas nécessaire d'appeler toObject () ou toJSON (). La __proto__ dans la question venait de JQuery, pas de mangouste. Voici mon test:

UserModel.find({}, function (err, users) {
    console.log(users.save);    // { [Function] numAsyncPres: 0 }
    var json = JSON.stringify(users);
    users = users.map(function (user) {
        return user.toObject();
    }
    console.log(user.save);    // undefined
    console.log(json == JSON.stringify(users));    // true
}

doc.toObject () supprime doc.prototype d'un doc. Mais cela ne fait aucune différence dans JSON.stringify (doc). Et ce n'est pas nécessaire dans ce cas.

6
Trantor Liu

Peut-être un peu égaré à la réponse, mais si quelqu'un cherche à faire l'inverse, vous pouvez utiliser Model.hydrate() (depuis mongoose v4) pour convertir un objet javascript (JSON) en un document mangouste.

Un cas utile serait lorsque vous utilisez Model.aggregate(...). Parce qu'il renvoie en fait un objet JS simple, vous pouvez donc le convertir en document mangouste pour pouvoir accéder à Model.method _ (par exemple, votre propriété virtuelle définie dans le schéma).

PS Je pensais qu'il devrait y avoir un fil d'exécution comme "Convertir JSON en documents Mongoose", mais en fait pas, et depuis que j'ai trouvé la réponse, je pense donc qu'il n'est pas bon de poster soi-même -et-auto-réponse.

2
Leo Li

Vous pouvez utiliser res.json () pour modifier n'importe quel objet. lean () supprimera tous les champs vides de la requête de mangouste.

UserModel.find().lean().exec(function (err, users) { return res.json(users); }

1
bindaas

Essayez ces options:

  UserModel.find({}, function (err, users) {
    return res.end( JSON.parse(JSON.stringify(users)) );
    //Or: 
    //return JSON.parse(JSON.stringify(users));
  }
1
Dudi

Cela a fonctionné pour moi:

Products.find({}).then(a => console.log(a.map(p => p.toJSON())))


aussi si vous voulez utiliser des accesseurs, vous devriez aussi ajouter son option (lors de la définition du schéma):

new mongoose.Schema({...}, {toJSON: {getters: true}})

0
yaya