我正在寻找一种方法来重构我的部分代码,使其更短更简单,但我不太了解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
和其他相关方法,但我不确定它们是否适合我的用例,或者我是否理解如何正确使用它们。有人能指出我正确的方向吗?
(可能)相关问题:
在我的搜索中,我没有遇到向我指出的问题,但在回顾了那里的答案后,我想出了这个。在我看来,它确实更漂亮,并且它有效,所以除非我做了一些可怕的错误,否则我认为我的问题可能会被关闭。
我很感激我的解决方案的任何其他输入。
// 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;
}
});
}
});
答案 0 :(得分:76)
您正在寻找new
选项参数。 new
选项返回新创建的文档(如果创建了新文档)。像这样使用它:
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
创建了文档但未找到文档,因此您无需手动创建另一个文档。
答案 1 :(得分:3)
由于您希望将代码的一部分重构得更短,更简单,所以
async / await
.findOneAndUpdate()
的建议使用answer let query = { /* query */ };
let update = {expire: new Date()};
let options = {upsert: true, new: true, setDefaultsOnInsert: true};
let model = await Model.findOneAndUpdate(query, update, options);
答案 2 :(得分:0)
@Service class MyService {
JpaRepository<B> repository;
public void accept(List<B> items) {
List<B> summed =
items.stream().collect(groupingBy(B::getName, summarizingDouble(B::getWeight)))
.entrySet().stream().map(e -> new B(e.getKey(), e.getValue()))
.collect(toList());
repository.save(summed);
}
}
答案 3 :(得分:-1)
这是一个例子:
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);
}
})
});