Konvertieren Sie Mongoose-Dokumente in json


76

Ich habe Mungo-Dokumente wie folgt als json zurückgegeben:

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

Benutzer .__ proto__ wurde jedoch ebenfalls zurückgegeben. Wie kann ich ohne zurückkehren? Ich habe es versucht, aber nicht funktioniert:

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

Antworten:


148

Sie können auch mongoosejs ' lean () ausprobieren :

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

1
OK, es scheint die Antwort zu sein.
Trantor Liu

9
Sollte es nicht sein: JSON.stringify(users);Da die zurückgegebenen Dokumente lean()einfache JS-Objekte sind?
Enyo

Ja, du hast recht, danke. JSON.stringify (Benutzer) sollte verwendet werden.
Ecdeveloper

Wenn Sie das Mungo-Instanzobjekt nach dem Abfragen der Datenbank weiterhin in der Rückruffunktion verwenden möchten, sollten Sie die leanFunktion nicht verwenden . Siehe meine Antwort für die Lösung. :)
eAbi

1
Vorsicht, lean()wird virtuelle Eigenschaften entfernen
Emmanuel NK

53

Späte Antwort, aber Sie können dies auch versuchen, wenn Sie Ihr Schema definieren.

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

Beachten Sie, dass dies retdas JSON-Objekt ist und keine Instanz des Mungomodells. Sie arbeiten direkt an Objekt-Hashes ohne Getter / Setter.

Und dann:

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

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

Bearbeiten: Februar 2015

Da ich keine Lösung für die fehlenden toJSON- (oder toObject-) Methoden bereitgestellt habe, werde ich den Unterschied zwischen meinem Verwendungsbeispiel und dem Verwendungsbeispiel von OP erläutern.

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

Mein Beispiel:

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

3
Es ist der beste Weg.
Daniel Kmak

toJSON () nicht definiert
OMGPOP

@eAbi sowohl toJSON als auch toObject sind nicht definiert
OMGPOP

@OMGPOP Sowohl toJSON als auch toObject sind Methoden, die für Mungo-Modellinstanzen definiert sind. Sie können entweder Ihr Verwendungsbeispiel angeben oder eine andere Frage zum Stackoverflow stellen. Soweit ich weiß, wurden sowohl die toJSON- als auch die toObject-Methode unabhängig von der verwendeten Mongoose-Version nicht veraltet / entfernt.
eAbi

2
@OMGPOP Ja, ich bin sicher, dass ich die toJSON-Methode verwende. Der Unterschied zwischen dem Verwendungsbeispiel von OP und meinem besteht darin, dass in der Frage von OP die zurückgegebene usersVariable ein Array von Mungo-Instanzen ist. Sie müssen das Array durchlaufen und die toJSON-Methode für jede Instanz aufrufen. In meinem Beispiel verwende ich die findById-Methode, die die gefundene Mungo-Instanz direkt an die Rückruffunktion übergibt. Anschließend können Sie die Methode toJSON (oder toObject) für diese Instanz direkt aufrufen.
eAbi

25

Versuchen Sie es zuerst toObject()statt toJSON()vielleicht?

Zweitens müssen Sie es auf den tatsächlichen Dokumenten und nicht auf dem Array aufrufen. Versuchen Sie also vielleicht etwas ärgerlicheres wie dieses:

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

Es ist eine Vermutung, aber ich hoffe, es hilft


Es ist so ärgerlich, es abbilden zu müssen. Gibt es nicht etwas in der Bibliothek, um das zu tun?
Anthony

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

  res.send(JSON.parse(JSON.stringify(docs)))
});

Dies ist die beste Antwort auf diese Frage. Die 'Magie', die die technischen Bereiche des Mungos verbirgt, scheint irgendwo hinter JSON.stringify verborgen zu sein.
Mischka

8

Ich habe herausgefunden, dass ich einen Fehler gemacht habe. Es ist überhaupt nicht erforderlich, toObject () oder toJSON () aufzurufen. Das __proto__ in der Frage stammte von jquery, nicht von Mungo. Hier ist mein 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 () entfernt doc.prototype aus einem Dokument. In JSON.stringify (doc) macht dies jedoch keinen Unterschied. Und es wird in diesem Fall nicht benötigt.


3

Vielleicht ein bisschen irre in die Antwort, aber wenn jemand anders herum will, können Sie Model.hydrate()(seit Mungo v4) ein Javascript-Objekt (JSON) in ein Mungo-Dokument konvertieren.

Ein nützlicher Fall wäre, wenn Sie verwenden Model.aggregate(...). Da es sich tatsächlich um ein einfaches JS-Objekt handelt, möchten Sie es möglicherweise in ein Mungodokument konvertieren, um Zugriff darauf zu erhalten Model.method(z. B. Ihre im Schema definierte virtuelle Eigenschaft).

PS. Ich dachte, es sollte einen Thread haben, der wie " Json in Mongoose-Dokumente konvertieren " läuft , aber eigentlich nicht, und da ich die Antwort herausgefunden habe, denke ich, dass es nicht gut ist, Selbst-Post-und-Selbst-Antwort zu machen.


2

Sie können res.json () verwenden, um jedes Objekt zu jsonifizieren. lean () entfernt alle leeren Felder in der Mungo-Abfrage.

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


2

Probieren Sie diese Optionen aus:

  UserModel.find({}, function (err, users) {
    //i got into errors using so i changed to res.send()
    return res.send( JSON.parse(JSON.stringify(users)) );
    //Or
    //return JSON.parse(JSON.stringify(users));
  }

1

Es hat bei mir funktioniert:

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


Wenn Sie Getter verwenden möchten, sollten Sie auch die Option hinzufügen (beim Definieren des Schemas):

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.