Ich suche nach einer Möglichkeit, einen Teil meines Codes kürzer und einfacher umzugestalten, aber ich kenne Mongoose nicht sehr gut und bin mir nicht sicher, wie ich vorgehen soll.
Ich versuche, eine Sammlung auf das Vorhandensein eines Dokuments zu überprüfen und es zu erstellen, falls es nicht vorhanden ist. Wenn es existiert, muss ich es aktualisieren. In beiden Fällen muss ich anschließend auf den Inhalt des Dokuments zugreifen.
Was ich bisher geschafft habe, ist, die Sammlung nach einem bestimmten Dokument abzufragen und, falls es nicht gefunden wird, ein neues Dokument zu erstellen. Wenn es gefunden wird, aktualisiere ich es (derzeit werden Daten als Dummy-Daten verwendet). Von dort aus kann ich entweder auf das gefundene Dokument aus meiner ersten find
Operation oder auf das neu gespeicherte Dokument zugreifen, und dies funktioniert, aber es muss einen besseren Weg geben, um das zu erreichen, wonach ich suche.
Hier ist mein Arbeitscode ohne ablenkende Extras.
var query = Model.find({
/* query */
}).lean().limit(1);
// Find the document
query.exec(function(error, result) {
if (error) { throw error; }
// If the document doesn't exist
if (!result.length) {
// Create a new one
var model = new Model(); //use the defaults in the schema
model.save(function(error) {
if (error) { throw error; }
// do something with the document here
});
}
// If the document does exist
else {
// Update it
var query = { /* query */ },
update = {},
options = {};
Model.update(query, update, options, function(error) {
if (error) { throw error; }
// do the same something with the document here
// in this case, using result[0] from the topmost query
});
}
});
Ich habe mich findOneAndUpdate
mit anderen verwandten Methoden befasst, bin mir aber nicht sicher, ob sie zu meinem Anwendungsfall passen oder ob ich verstehe, wie man sie richtig verwendet. Kann mich jemand in die richtige Richtung weisen?
(Wahrscheinlich) Verwandte Fragen:
- So überprüfen Sie, ob diese Daten während des Updates bereits in der Datenbank vorhanden sind (Mongoose And Express)
- Mongoose.js: Wie implementiere ich create oder update?
- NodeJS + Mongo: Einfügen, falls nicht vorhanden, andernfalls aktualisieren
- Geben Sie die aktualisierte Sammlung mit Mongoose zurück
Bearbeiten
Ich bin bei meiner Suche nicht auf die Frage gestoßen, auf die ich hingewiesen wurde, aber nachdem ich die Antworten dort überprüft habe, bin ich darauf gekommen. Meiner Meinung nach ist es sicherlich hübscher und es funktioniert. Wenn ich also nichts Schreckliches falsch mache, denke ich, dass meine Frage wahrscheinlich geschlossen werden kann.
Ich würde mich über zusätzliche Beiträge zu meiner Lösung freuen.
// Setup stuff
var query = { /* query */ },
update = { expire: new Date() },
options = { upsert: true };
// Find the document
Model.findOneAndUpdate(query, update, options, function(error, result) {
if (!error) {
// If the document doesn't exist
if (!result) {
// Create it
result = new Model();
}
// Save the document
result.save(function(error) {
if (!error) {
// Do something with the document
} else {
throw error;
}
});
}
});
quelle
Antworten:
Sie suchen die
new
Optionsparameter. Dienew
Option gibt das neu erstellte Dokument zurück (wenn ein neues Dokument erstellt wird). Verwenden Sie es so:var query = {}, update = { expire: new Date() }, options = { upsert: true, new: true, setDefaultsOnInsert: true }; // Find the document Model.findOneAndUpdate(query, update, options, function(error, result) { if (error) return; // do something with the document });
Da
upsert
ein Dokument erstellt wird, wenn kein Dokument gefunden wird, müssen Sie kein weiteres manuell erstellen.quelle
Da Sie Teile Ihres Codes so umgestalten möchten, dass sie kürzer und einfacher sind,
async / await
.findOneAndUpdate()
wie in dieser Antwort vorgeschlagenlet query = { /* query */ }; let update = {expire: new Date()}; let options = {upsert: true, new: true, setDefaultsOnInsert: true}; let model = await Model.findOneAndUpdate(query, update, options);
quelle
///This is simple example explaining findByIDAndUpdate from my code added with try catch block to catch errors try{ const options = { upsert: true, new: true, setDefaultsOnInsert: true }; const query = { $set: { description: req.body.description, title: req.body.title } }; const survey = await Survey.findByIdAndUpdate( req.params.id, query, options ).populate("questions"); }catch(e){ console.log(e) }
quelle
Hier ist ein Beispiel:
const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/rsvp', {useNewUrlParser: true, useUnifiedTopology: true}); const db = mongoose.connection; db.on('error', () => { console.log('mongoose connection error'); }); db.once('open', () => { console.log('mongoose connected successfully'); }); const rsvpSchema = mongoose.Schema({ firstName: String, lastName: String, email: String, guests: Number }); const Rsvp = mongoose.model('Rsvp', rsvpSchema); // This is the part you will need... In this example, if first and last name match, update email and guest number. Otherwise, create a new document. The key is to learn to put "upsert" as the "options" for the argument. const findRsvpAndUpdate = (result, callback) => { Rsvp.findOneAndUpdate({firstName: result.firstName, lastName: result.lastName}, result, { upsert: true }, (err, results) => { if (err) { callback(err); } else { callback(null, results); } }) }; // From your server index.js file, call this... app.post('/rsvps', (req, res) => { findRsvpAndUpdate(req.body, (error, result) => { if (error) { res.status(500).send(error); } else { res.status(200).send(result); } }) });
quelle