Mongoose 是否支持 Mongodb `findAndModify` 方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7334390/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does Mongoose support the Mongodb `findAndModify` method?
提问by Raja
I would like to use findAndModify to atomically increment a field, using Mongoose.
我想使用 findAndModify 使用 Mongoose 以原子方式递增字段。
However, the code below throws the error "TypeError: Object # has no method 'findAndModify'":
但是,下面的代码会抛出错误“TypeError: Object # has no method 'findAndModify'”:
// defining schema for the "counters" table
var tableSchema = new Schema({
_id: String,
next: Number
});
// creating table object for the counters table
var counters_table = mongoose.model('counters', tableSchema);
var tableObj = new counters_table();
// increment the "next" field on the table object
var query = {_id: 'messagetransaction'};
var update = {'$inc': {next: 1}};
var ret = tableObj.findAndModify(query, [], update, true, true, function(err) {
if (err) {
throw err;
}
else {
console.log("updated!");
}
});
回答by furf
The feature is not well (read: at all) documented, but after reading through the source code, I came up with the following solution.
该功能没有很好地(阅读:根本)记录,但在阅读源代码后,我想出了以下解决方案。
Create your collection schema.
创建您的集合模式。
var Counters = new Schema({
_id: String,
next: Number
});
Create a static method on the schema which will expose the findAndModify method of the model's collection.
在架构上创建一个静态方法,它将公开模型集合的 findAndModify 方法。
Counters.statics.findAndModify = function (query, sort, doc, options, callback) {
return this.collection.findAndModify(query, sort, doc, options, callback);
};
Create your model.
创建您的模型。
var Counter = mongoose.model('counters', Counters);
Find and modify!
查找和修改!
Counter.findAndModify({ _id: 'messagetransaction' }, [], { $inc: { next: 1 } }, {}, function (err, counter) {
if (err) throw err;
console.log('updated, counter is ' + counter.next);
});
Bonus
奖金
Counters.statics.increment = function (counter, callback) {
return this.collection.findAndModify({ _id: counter }, [], { $inc: { next: 1 } }, callback);
};
Counter.increment('messagetransaction', callback);
回答by juanpaco
This is fully supported in Mongoose 3.x now, though the name is slightly different.
现在在 Mongoose 3.x 中完全支持,尽管名称略有不同。
http://mongoosejs.com/docs/api.html#model_Model.findOneAndUpdate
http://mongoosejs.com/docs/api.html#model_Model.findOneAndUpdate
http://mongoosejs.com/docs/api.html#model_Model.findByIdAndUpdate
http://mongoosejs.com/docs/api.html#model_Model.findByIdAndUpdate
http://mongoosejs.com/docs/api.html#model_Model.findOneAndRemove
http://mongoosejs.com/docs/api.html#model_Model.findOneAndRemove
http://mongoosejs.com/docs/api.html#model_Model.findByIdAndRemove
http://mongoosejs.com/docs/api.html#model_Model.findByIdAndRemove
回答by Klimashkin
Made working version increment for Mongoose 3.x
为 Mongoose 3.x 制作工作版本增量
var mongoose = require('mongoose');
var CounterSchema = new mongoose.Schema({
_id: String,
next: {type: Number, default: 1}
});
CounterSchema.statics.increment = function (counter, callback) {
return this.findByIdAndUpdate(counter, { $inc: { next: 1 } }, {new: true, upsert: true, select: {next: 1}}, callback);
};
Use something like this:
使用这样的东西:
Counter.increment('photo', function (err, result) {
if (err) {
console.error('Counter on photo save error: ' + err); return;
}
photo.cid = result.next;
photo.save();
});
I hope someone come in handy
我希望有人能派上用场
回答by ninja123
In version 3, the mongoose findOneAndUpdate method exposes mongodb's findAndModify operation. It works like so:
在版本 3 中,mongoose findOneAndUpdate 方法公开了 mongodb 的 findAndModify 操作。它的工作原理是这样的:
var query = { name: 'Sprinkls' };
var update = { name: 'Sprinkles' };
var options = { new: false };
Cat.findOneAndUpdate(query, update, options, function (err, cat) {
if (err) ..
render('cat', cat);
});
More info here: http://aaronheckmann.tumblr.com/post/48943524629/mongoose-v3-part-2-findandmodify
更多信息:http: //aaronheckmann.tumblr.com/post/48943524629/mongoose-v3-part-2-findandmodify
回答by keithics
a lot of answers but I find this simple solution.
很多答案,但我找到了这个简单的解决方案。
Counter.findByIdAndUpdate(ID, {$inc: {next:1}}, function (err, data) {
});
回答by Curran
I got findAndModify to
我找到了 findAndModify
- Upsert a counter (create and initialize it if it doesn't exist)
- Increment the counter
- Call a callback with the incremented value
- 向上插入一个计数器(如果它不存在则创建并初始化它)
- 增加计数器
- 使用递增的值调用回调
in a single DB roundtrip using the following code:
在使用以下代码的单个数据库往返中:
var Counters = new Schema({
_id:String, // the schema name
count: Number
});
Counters.statics.findAndModify = function (query, sort, doc, options, callback) {
return this.collection.findAndModify(query, sort, doc, options, callback);
};
var Counter = mongoose.model('Counter', Counters);
/**
* Increments the counter associated with the given schema name.
* @param {string} schemaName The name of the schema for which to
* increment the associated counter.
* @param {function(err, count)} The callback called with the updated
* count (a Number).
*/
function incrementCounter(schemaName, callback){
Counter.findAndModify({ _id: schemaName }, [],
{ $inc: { count: 1 } }, {"new":true, upsert:true}, function (err, result) {
if (err)
callback(err);
else
callback(null, result.count);
});
}
Enjoy! - Curran
享受!- 可兰
回答by David
Taking the above response from @furf, this is my promised
solution:
从@furf得到上述回应,这是我的promised
解决方案:
// eslint-disable-next-line func-names
localeTypesSchema.statics.findAndModify = function (query, sort, update, opts, callback) {
const cb = callback || (() => { });
try {
const result = this.collection.findAndModify(query || {}, sort || [], update || {}, opts);
cb(null, result);
return Promise.resolve(result);
} catch (err) {
cb(err);
return Promise.reject(err);
}
};
回答by mstearn
I would suggest using the direct command style shown at the bottom of http://www.mongodb.org/display/DOCS/findAndModify+Command. I'm not familiar enough with mongoose to know the method for running a command, but all drivers provide some way to do it. If mongoose doesn't, you can do it directly using the style described at the top of http://www.mongodb.org/display/DOCS/Commands.
我建议使用http://www.mongodb.org/display/DOCS/findAndModify+Command底部显示的直接命令样式。我对 mongoose 不够熟悉,不知道运行命令的方法,但所有驱动程序都提供了一些方法来做到这一点。如果 mongoose 没有,您可以直接使用http://www.mongodb.org/display/DOCS/Commands顶部描述的样式来完成。
That said, you should make sure that you really need findAndModify
and that update
won't do what you need it to do. To see what update
is capable of take a look at http://www.mongodb.org/display/DOCS/Updating.
也就是说,您应该确保您确实需要findAndModify
并且update
不会做您需要它做的事情。要了解update
可以查看哪些内容,请访问http://www.mongodb.org/display/DOCS/Updating。
回答by Jonathan David
just adding to furf answer that if you use objectId in your query, mongoDB will not be able to find your document. The mongoose layer takes care of converting the Hex string object id you get from the routing params to the proper object id.
只是添加到 furf 答案中,如果您在查询中使用 objectId,mongoDB 将无法找到您的文档。猫鼬层负责将您从路由参数获得的十六进制字符串对象 id 转换为正确的对象 id。
to solve this you need to:
要解决这个问题,您需要:
var ObjectID = require('mongodb').ObjectID;
var itemId = req.params.itemId;
var objectId = ObjectID.createFromHexString(itemId);
Item.findAndModify({_id: objectId},