Mongoose - 如果不存在则创建文档,否则,在任何一种情况下都更新 - return 文档
Mongoose - Create document if not exists, otherwise, update- return document in either case
我正在寻找一种方法来重构我的部分代码,使其更短更简单,但我对 Mongoose 不是很了解,我不确定如何进行。
我正在尝试检查集合中是否存在文档,如果不存在,则创建它。如果它确实存在,我需要更新它。无论哪种情况,之后我都需要访问文档的内容。
到目前为止,我所做的是查询特定文档的集合,如果未找到,则创建一个新文档。如果找到,我会更新它(目前使用日期作为虚拟数据)。从那里我可以访问从我最初的 find
操作中找到的文档或新保存的文档并且这有效,但必须有更好的方法来完成我所追求的。
这是我的工作代码,没有让人分心的额外内容。
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
});
}
});
我研究了 findOneAndUpdate
和其他相关方法,但我不确定它们是否适合我的用例,或者我是否了解如何正确使用它们。谁能指出我正确的方向?
(大概)相关问题:
- How to check if that data already exist in the database during update (Mongoose And Express)
- Mongoose.js: how to implement create or update?
- NodeJS + Mongo: Insert if not exists, otherwise - update
- Return updated collection with Mongoose
编辑
我在搜索时没有遇到向我指出的问题,但在查看那里的答案后我想出了这个问题。在我看来,它肯定更漂亮,而且有效,所以除非我做错了什么,否则我认为我的问题可能会被关闭。
如果您对我的解决方案有任何补充意见,我将不胜感激。
// 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;
}
});
}
});
您正在查找 new
选项参数。 new
选项 returns 新创建的文档(如果创建了新文档)。像这样使用它:
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
});
由于 upsert
如果找不到文档就会创建一个文档,因此您无需手动创建另一个文档。
由于您希望重构部分代码以使其更短更简单,
- 使用
async / await
- 使用
.findOneAndUpdate()
as suggested in this
let 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)
}
这是一个例子:
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);
}
})
});
这是我正在使用的示例。我必须 return 为 UI 更新等自定义响应。这可以更短。用户是
const UserScheme = mongoose.Schema({
_id: String,
name: String,
city: String,
address: String,
},{timestamps: true});
const User = mongoose.model('Users', UserScheme);
async function userUpdateAdd(data){
var resp = '{"status": "error"}';
if(data){
var resp = await User.updateOne({ _id: data._id }, data).then(function(err, res){
console.log("database.userUpdateAdd -> Update data saved in database!");
if(err){
var errMessage = err.matchedCount == 0 ? "User Record does not exist, will create new..." : "Record not updated";
// If no match, create new
if(err.matchedCount == 0){
const create_user = new User(data);
resp = create_user.save().then(function(){
console.log("database.userUpdateAdd -> Data saved to database!");
return '{"status":"success", "message": "New User added successfully"}';
});
return resp;
}
// Exists, return success update message
if(err.matchedCount == 1){
return '{"status": "success", "message" : "Update saved successfully"}';
} else {
return '{"status": "error", "code": "' + err.modifiedCount + '", "message": "' + errMessage + '"}';
}
}
})
.catch((error) => {
//When there are errors We handle them here
console.log("database.userUpdateAdd -> Error, data not saved! Server error");
return '{"status": "error", "code": "400", "message": "Server error!"}';
});
}
return resp;
}
我正在寻找一种方法来重构我的部分代码,使其更短更简单,但我对 Mongoose 不是很了解,我不确定如何进行。
我正在尝试检查集合中是否存在文档,如果不存在,则创建它。如果它确实存在,我需要更新它。无论哪种情况,之后我都需要访问文档的内容。
到目前为止,我所做的是查询特定文档的集合,如果未找到,则创建一个新文档。如果找到,我会更新它(目前使用日期作为虚拟数据)。从那里我可以访问从我最初的 find
操作中找到的文档或新保存的文档并且这有效,但必须有更好的方法来完成我所追求的。
这是我的工作代码,没有让人分心的额外内容。
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
});
}
});
我研究了 findOneAndUpdate
和其他相关方法,但我不确定它们是否适合我的用例,或者我是否了解如何正确使用它们。谁能指出我正确的方向?
(大概)相关问题:
- How to check if that data already exist in the database during update (Mongoose And Express)
- Mongoose.js: how to implement create or update?
- NodeJS + Mongo: Insert if not exists, otherwise - update
- Return updated collection with Mongoose
编辑
我在搜索时没有遇到向我指出的问题,但在查看那里的答案后我想出了这个问题。在我看来,它肯定更漂亮,而且有效,所以除非我做错了什么,否则我认为我的问题可能会被关闭。
如果您对我的解决方案有任何补充意见,我将不胜感激。
// 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;
}
});
}
});
您正在查找 new
选项参数。 new
选项 returns 新创建的文档(如果创建了新文档)。像这样使用它:
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
});
由于 upsert
如果找不到文档就会创建一个文档,因此您无需手动创建另一个文档。
由于您希望重构部分代码以使其更短更简单,
- 使用
async / await
- 使用
.findOneAndUpdate()
as suggested in this
let 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)
}
这是一个例子:
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);
}
})
});
这是我正在使用的示例。我必须 return 为 UI 更新等自定义响应。这可以更短。用户是
const UserScheme = mongoose.Schema({
_id: String,
name: String,
city: String,
address: String,
},{timestamps: true});
const User = mongoose.model('Users', UserScheme);
async function userUpdateAdd(data){
var resp = '{"status": "error"}';
if(data){
var resp = await User.updateOne({ _id: data._id }, data).then(function(err, res){
console.log("database.userUpdateAdd -> Update data saved in database!");
if(err){
var errMessage = err.matchedCount == 0 ? "User Record does not exist, will create new..." : "Record not updated";
// If no match, create new
if(err.matchedCount == 0){
const create_user = new User(data);
resp = create_user.save().then(function(){
console.log("database.userUpdateAdd -> Data saved to database!");
return '{"status":"success", "message": "New User added successfully"}';
});
return resp;
}
// Exists, return success update message
if(err.matchedCount == 1){
return '{"status": "success", "message" : "Update saved successfully"}';
} else {
return '{"status": "error", "code": "' + err.modifiedCount + '", "message": "' + errMessage + '"}';
}
}
})
.catch((error) => {
//When there are errors We handle them here
console.log("database.userUpdateAdd -> Error, data not saved! Server error");
return '{"status": "error", "code": "400", "message": "Server error!"}';
});
}
return resp;
}