Selon cet article de mongodb il est possible d’auto incrémenter un champ et je voudrais utiliser la méthode de collecte des compteurs.
Le problème avec cet exemple est que des milliers de personnes ne saisissent pas les données de la base de données à l'aide de la console mongo. Au lieu de cela, j'essaie d'utiliser de la mangouste.
Donc, mon schéma ressemble à ceci:
var entitySchema = mongoose.Schema({
testvalue:{type:String,default:function getNextSequence() {
console.log('what is this:',mongoose);//this is mongoose
var ret = db.counters.findAndModify({
query: { _id:'entityId' },
update: { $inc: { seq: 1 } },
new: true
}
);
return ret.seq;
}
}
});
J'ai créé la collection de compteurs dans la même base de données et ajouté une page avec l'identifiant _id de 'entityId'. À partir de là, je ne suis pas sûr de savoir comment utiliser mangouste pour mettre à jour cette page et obtenir le numéro incrémenté.
Il n'y a pas de schéma pour les compteurs et j'aimerais qu'il en reste ainsi, car il ne s'agit pas vraiment d'une entité utilisée par l'application. Il ne doit être utilisé que dans les schémas pour incrémenter automatiquement les champs.
Voici un exemple d'utilisation du champ à incrémentation automatique dans Mongoose:
var CounterSchema = Schema({
_id: {type: String, required: true},
seq: { type: Number, default: 0 }
});
var counter = mongoose.model('counter', CounterSchema);
var entitySchema = mongoose.Schema({
testvalue: {type: String}
});
entitySchema.pre('save', function(next) {
var doc = this;
counter.findByIdAndUpdate({_id: 'entityId'}, {$inc: { seq: 1} }, function(error, counter) {
if(error)
return next(error);
doc.testvalue = counter.seq;
next();
});
});
Vous pouvez utiliser le package mongoose-auto-increment
comme suit:
var mongoose = require('mongoose');
var autoIncrement = require('mongoose-auto-increment');
/* connect to your database here */
/* define your CounterSchema here */
autoIncrement.initialize(mongoose.connection);
CounterSchema.plugin(autoIncrement.plugin, 'Counter');
var Counter = mongoose.model('Counter', CounterSchema);
Vous devez seulement initialiser la autoIncrement
une fois.
La réponse la plus votée ne fonctionne pas. C'est le correctif:
var CounterSchema = new mongoose.Schema({
_id: {type: String, required: true},
seq: { type: Number, default: 0 }
});
var counter = mongoose.model('counter', CounterSchema);
var entitySchema = mongoose.Schema({
sort: {type: String}
});
entitySchema.pre('save', function(next) {
var doc = this;
counter.findByIdAndUpdateAsync({_id: 'entityId'}, {$inc: { seq: 1} }, {new: true, upsert: true}).then(function(count) {
console.log("...count: "+JSON.stringify(count));
doc.sort = count.seq;
next();
})
.catch(function(error) {
console.error("counter error-> : "+error);
throw error;
});
});
Les paramètres options vous donnent le résultat de la mise à jour et créent un nouveau document s'il n'existe pas .. Vous pouvez vérifier ici le document officiel.
Et si vous avez besoin d’un index trié, cochez doc
Je sais que cela a déjà beaucoup de réponses, mais je partagerais ma solution qui est courte et facile à comprendre pour l'OMI:
// Use pre middleware
entitySchema.pre('save', function (next) {
// Only increment when the document is new
if (this.isNew) {
entityModel.count().then(res => {
this._id = res; // Increment count
next();
});
} else {
next();
}
});
Assurez-vous que entitySchema._id
a type:Number
. Version Mongoose: 5.0.1
.
Je ne souhaitais utiliser aucun plugin (une dépendance supplémentaire, initialisant la connexion mongodb en plus de celle que j’utilise dans le server.js, etc ...) donc j’ai fait un module supplémentaire, je peux l’utiliser dans n’importe quel schéma et même, je songe à supprimer un document de la base de données.
module.exports = async function(model, data, next) {
// Only applies to new documents, so updating with model.save() method won't update id
// We search for the biggest id into the documents (will search in the model, not whole db
// We limit the search to one result, in descendant order.
if(data.isNew) {
let total = await model.find().sort({id: -1}).limit(1);
data.id = total.length === 0 ? 1 : Number(total[0].id) + 1;
next();
};
};
Et comment l'utiliser:
const autoincremental = require('../modules/auto-incremental');
Work.pre('save', function(next) {
autoincremental(model, this, next);
// Arguments:
// model: The model const here below
// this: The schema, the body of the document you wan to save
// next: next fn to continue
});
const model = mongoose.model('Work', Work);
module.exports = model;
J'espère que ça vous aide.
(Si cela ne va pas, merci de me le dire. Je n'ai eu aucun problème avec cela, mais pas un expert)
Vous pouvez également utiliser des paquets externes fournis par mangouste (facile à comprendre).
J'utilise ensemble @ cluny85 et @edtech . Mais je ne termine pas la finition ce problème.
counterModel.findByIdAndUpdate({_id: 'aid'}, {$inc: { seq: 1} }, function(error,counter){
Mais dans la fonction "pre ('save ...) puis la réponse du compteur de mise à jour se termine après la sauvegarde du document . Je ne mets donc pas à jour le compteur à document.
Veuillez vérifier à nouveau toutes les réponses. Merci.
Pardon. Je ne peux pas ajouter de commentaire. Parce que je suis novice.
Donc, en combinant plusieurs réponses, voici ce que j’ai utilisé:
counterModel.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
const counterSchema = new Schema(
{
_id: {type: String, required: true},
seq: { type: Number, default: 0 }
}
);
counterSchema.index({ _id: 1, seq: 1 }, { unique: true })
const counterModel = mongoose.model('counter', counterSchema);
const autoIncrementModelID = function (modelName, doc, next) {
counterModel.findByIdAndUpdate( // ** Method call begins **
modelName, // The ID to find for in counters model
{ $inc: { seq: 1 } }, // The update
{ new: true, upsert: true }, // The options
function(error, counter) { // The callback
if(error) return next(error);
doc.id = counter.seq;
next();
}
); // ** Method call ends **
}
module.exports = autoIncrementModelID;
myModel.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
const autoIncrementModelID = require('./counterModel');
const myModel = new Schema({
id: { type: Number, unique: true, min: 1 },
createdAt: { type: Date, default: Date.now },
updatedAt: { type: Date },
someOtherField: { type: String }
});
myModel.pre('save', function (next) {
if (!this.isNew) {
next();
return;
}
autoIncrementModelID('activities', this, next);
});
module.exports = mongoose.model('myModel', myModel);
var CounterSchema = Schema({
_id: { type: String, required: true },
seq: { type: Number, default: 0 }
});
var counter = mongoose.model('counter', CounterSchema);
var entitySchema = mongoose.Schema({
testvalue: { type: String }
});
entitySchema.pre('save', function(next) {
if (this.isNew) {
var doc = this;
counter.findByIdAndUpdate({ _id: 'entityId' }, { $inc: { seq: 1 } }, { new: true, upsert: true })
.then(function(count) {
doc.testvalue = count.seq;
next();
})
.catch(function(error) {
throw error;
});
} else {
next();
}
});