Javascript 如何在猫鼬中创建/查找?
有时我需要一个文档存在于数据库中,我很乐意使用现有的文档,或者创建缺少的文档,然后使用新文档 这似乎是一个相当常见的用例,但我已经查看了,但找不到任何东西 Mongoose收集方法,如Javascript 如何在猫鼬中创建/查找?,javascript,node.js,mongodb,mongoose,Javascript,Node.js,Mongodb,Mongoose,有时我需要一个文档存在于数据库中,我很乐意使用现有的文档,或者创建缺少的文档,然后使用新文档 这似乎是一个相当常见的用例,但我已经查看了,但找不到任何东西 Mongoose收集方法,如findOneAndUpdate()和update()和upsert:true都是关于修改文档的-如果文档存在,我不想修改它,只要获取它的引用即可 示例:(为@neillunn添加)我想添加一个用户,该用户引用的公司的“名称”为“foo”。在此之前,我想查找一个名为{name:'foo'}的公司,如果它不存在,就创
findOneAndUpdate()
和update()
和upsert:true
都是关于修改文档的-如果文档存在,我不想修改它,只要获取它的引用即可
示例:(为@neillunn添加)我想添加一个用户,该用户引用的公司的“名称”为“foo”。在此之前,我想查找一个名为{name:'foo'}
的公司,如果它不存在,就创建它
示例2:(为@neillunn添加)我现在用来处理示例场景的代码:
// Find or create an an instance and return a cb with a reference to it.
var findOrCreate = function(model, criteria, cb){
model.update(criteria, criteria, {upsert: true}, function(err, numberAffected, raw){
if ( ! raw.updatedExisting ) {
console.log('Created instance')
} else {
console.log('Found existing instance')
}
model.findOne(criteria, cb)
})
}
注意:
findOneAndUpdate()
将无法工作,因为它将尝试修改现有文档,并获取“重复键错误索引”如评论中所述,mongoose有一个插件可以做到这一点:
还描述了一种无需插件即可实现此功能的方法。我只是不确定它是否适用于猫鼬。非常有用的解决方案: 当习惯于承诺时更有趣:
Counters.statics.findAndModify =
function findAndModify(query, sort, update, options, callback) {
const promised = q.nbind(this.collection.findAndModify, this.collection);
return promised(query || {}, sort || [], update || {}, options, callback);
};
可以找到,如果数据不存在,它将创建数据。基本上如下所示:
var modelDoc = new MyModel({ foo: 'bar' });
MyModel.findOneAndUpdate(
{foo: 'bar'}, // find a document with that filter
modelDoc, // document to insert when nothing was found
{upsert: true, new: true, runValidators: true}, // options
function (err, doc) { // callback
if (err) {
// handle error
} else {
// handle document
}
}
);
options
参数对于使插入工作非常重要`
通过设置upsert:true
,如果{foo:'bar'}
过滤器未找到任何结果,则可以命令MongoDB将modelDoc文档实际添加到集合中
new:true
选项更改回调函数中返回的内容。如果为false,则文档将在更新前包含文档(或插入前为null)。如果为true,则文档包含更新或创建后的文档。虽然false是默认选项,但我想大多数人实际上更喜欢它为true
如果希望Mongoose运行验证程序,则必须设置
runValidators:true
选项。默认情况下,使用findOneAndUpdate()
不太清楚时,不会执行这些命令。您看到的是正确的东西,但为什么您只想基本上“查找”它是否存在,以及“修改/升级”它是否存在?这种差异似乎不言自明。也许可以更好地解释您的用例。那么您基本上希望实现自动关系?由于mongoose没有官方或程序支持关系,我认为您需要执行两个查询来实现这一点。@Charminbear Not relations,只是根据需要查找或制作。如果我的示例是因为需要引用公司而查找/创建公司实例。\u id
但这只是当前的用例。@Mikemacana:您正在搜索类似的内容?非常有用的解决方案:
var modelDoc = new MyModel({ foo: 'bar' });
MyModel.findOneAndUpdate(
{foo: 'bar'}, // find a document with that filter
modelDoc, // document to insert when nothing was found
{upsert: true, new: true, runValidators: true}, // options
function (err, doc) { // callback
if (err) {
// handle error
} else {
// handle document
}
}
);