我如何在Mongoose中创build/查找?
有时我需要在数据库中存在一个文档,并且很乐意使用现有的文档,或者在丢失文档的情况下创build文档,并使用新的文档。
这似乎是一个相当常见的用例,但我已经通过Mongoose文档看 ,我找不到任何东西。
像findOneAndUpdate()
和update()
和upsert: true
这样的Mongoose Collection方法是关于修改文档的 – 我不希望修改文档(如果存在的话),只是获取对它的引用。
示例 :(为@neillunn添加)我想添加一个用户,引用一个名字为“foo”的公司。 在此之前,我想用{name: 'foo'}
来查找一个公司,如果它不存在,就创build它。
示例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的插件是这样做的: http : //github.com/drudge/mongoose-findorcreate
本主题还描述了一种无插件实现的方法。 林只是不知道,但如果它适用于mongoose。
非常有用的解决scheme在这里: https : //stackoverflow.com/a/7592756/4025963 :
var Counters = new Schema({ _id: String, next: Number }); Counters.statics.findAndModify = function (query, sort, doc, options, callback) { return this.collection.findAndModify(query, sort, doc, options, callback); }; var Counter = mongoose.model('counters', Counters); Counter.findAndModify({ _id: 'messagetransaction' }, [], { $inc: { next: 1 } }, {}, function (err, counter) { if (err) throw err; console.log('updated, counter is ' + counter.next); });
用于承诺时更有意思:
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); };