multi - update array mongodb
¿Apoya Mongoose el método Mongodb `findAndModify`? (9)
En la versión 3, el método mongoose findOneAndUpdate expone la operación findAndModify de mongodb. Funciona así:
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);
});
Más información aquí: http://aaronheckmann.tumblr.com/post/48943524629/mongoose-v3-part-2-findandmodify
Me gustaría usar findAndModify para incrementar atómicamente un campo, usando Mongoose.
Sin embargo, el código siguiente arroja el error "TypeError: Object # no tiene el método ''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!");
}
});
Esto es totalmente compatible con Mongoose 3.x ahora, aunque el nombre es ligeramente diferente.
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.findByIdAndRemove
Incremento de versión de trabajo hecho para 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);
};
Usa algo como esto:
Counter.increment(''photo'', function (err, result) {
if (err) {
console.error(''Counter on photo save error: '' + err); return;
}
photo.cid = result.next;
photo.save();
});
Espero que alguien sea útil
La función no está bien (léase: en absoluto) documentada, pero después de leer el código fuente, se me ocurrió la siguiente solución.
Crea tu esquema de colección.
var Counters = new Schema({
_id: String,
next: Number
});
Cree un método estático en el esquema que expondrá el método findAndModify de la colección del modelo.
Counters.statics.findAndModify = function (query, sort, doc, options, callback) {
return this.collection.findAndModify(query, sort, doc, options, callback);
};
Crea tu modelo
var Counter = mongoose.model(''counters'', Counters);
Encuentra y modifica!
Counter.findAndModify({ _id: ''messagetransaction'' }, [], { $inc: { next: 1 } }, {}, function (err, counter) {
if (err) throw err;
console.log(''updated, counter is '' + counter.next);
});
Prima
Counters.statics.increment = function (counter, callback) {
return this.collection.findAndModify({ _id: counter }, [], { $inc: { next: 1 } }, callback);
};
Counter.increment(''messagetransaction'', callback);
Sugeriría usar el estilo de comando directo que se muestra en la parte inferior de http://www.mongodb.org/display/DOCS/findAndModify+Command . No estoy lo suficientemente familiarizado con la mangosta para conocer el método para ejecutar un comando, pero todos los controladores proporcionan alguna forma de hacerlo. Si la mangosta no lo hace, puede hacerlo directamente utilizando el estilo descrito en la parte superior de http://www.mongodb.org/display/DOCS/Commands .
Dicho esto, debe asegurarse de que realmente necesita findAndModify
y esa update
no hará lo que necesita hacer. Para ver qué update
es capaz de echar un vistazo a http://www.mongodb.org/display/DOCS/Updating .
Tengo findAndModify para
- Upsert a counter (crear e inicializar si no existe)
- Incrementa el contador
- Llamar a una devolución de llamada con el valor incrementado
en una ida y vuelta DB simple utilizando el siguiente código:
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);
});
}
¡Disfrutar! - Curran
Tomando la respuesta anterior de @furf , esta es mi solución 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);
}
};
muchas respuestas pero encuentro esta solución simple.
Counter.findByIdAndUpdate(ID, {$inc: {next:1}}, function (err, data) {
});
simplemente agregando a furf, responda que si usa objectId en su consulta, mongoDB no podrá encontrar su documento. La capa de mangosta se encarga de convertir el Id. De objeto de cadena hexadecimal que obtienes de los parámetros de enrutamiento al id de objeto adecuado.
Para resolver esto necesitas:
var ObjectID = require(''mongodb'').ObjectID;
var itemId = req.params.itemId;
var objectId = ObjectID.createFromHexString(itemId);
Item.findAndModify({_id: objectId},