Je cherche un moyen de reformuler une partie de mon code pour qu'il soit plus court et plus simple, mais je ne connais pas très bien Mongoose et je ne sais pas comment procéder.
J'essaie de vérifier l'existence d'un document dans une collection et, s'il n'existe pas, de le créer. S'il existe, je dois le mettre à jour. Dans les deux cas, je dois ensuite accéder au contenu du document.
Ce que j’ai réussi à faire jusqu’à présent, c’est d’interroger la collection sur un document spécifique et, si ce n’est pas trouvé, de créer un nouveau document. S'il est trouvé, je le mets à jour (en utilisant actuellement les dates comme données factices pour cela). À partir de là, je peux accéder au document trouvé de mon opération initiale find
ou au document nouvellement enregistré. Cela fonctionne, mais il doit exister un meilleur moyen d'accomplir ce que je recherche après.
Voici mon code de travail, sans suppléments distrayants.
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
});
}
});
J'ai examiné findOneAndUpdate
et d'autres méthodes associées, mais je ne sais pas si elles conviennent à mon cas d'utilisation ou si je comprends comment les utiliser correctement. Est-ce que quelqu'un peut-il me montrer la bonne direction?
(Probablement) Questions connexes:
Je ne suis pas tombé sur la question qui m’a été posée lors de mes recherches, mais après avoir examiné les réponses, j’ai trouvé ceci. À mon avis, c'est certainement plus joli et cela fonctionne. Donc, à moins que je ne fasse quelque chose de mal, je pense que ma question pourra probablement être close.
J'apprécierais toute contribution supplémentaire sur ma solution.
// 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;
}
});
}
});
Vous recherchez le paramètre d'option new
. L'option new
renvoie le document nouvellement créé (si un nouveau document est créé). Utilisez-le comme ceci:
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
});
Puisque upsert
crée un document s'il ne trouve pas de document, vous n'avez pas besoin de créer un autre manuellement.
Puisque vous souhaitez refactoriser des parties de votre code pour les rendre plus simples et plus courtes,
async / await
.findOneAndUpdate()
comme suggéré dans ce réponselet query = { /* query */ };
let update = {expire: new Date()};
let options = {upsert: true, new: true, setDefaultsOnInsert: true};
let model = await Model.findOneAndUpdate(query, update, options);
///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)
}