2015-02-06 23 views
11

Nach this mongodb article ist es möglich, ein Feld automatisch zu inkrementieren, und ich möchte die Zähler Sammlungsweise verwenden.Mongoose Autoinkrement

Das Problem mit diesem Beispiel ist, dass ich nicht habe Tausende von Menschen die Daten in der Datenbank mit der Mongo-Konsole eingeben. Stattdessen versuche ich, Mungo zu benutzen.

Also mein Schema sieht wie folgt aus:

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; 
     } 
    } 
}); 

ich den Zähler Sammlung in derselben Datenbank erstellt haben und eine Seite mit dem _id von ‚EntityID‘ hinzugefügt. Von hier bin ich nicht sicher, wie man Mungo benutzt, um diese Seite zu aktualisieren und die steigende Zahl zu erhalten.

Es gibt kein Schema für Counter und ich möchte, dass es so bleibt, weil dies nicht wirklich eine Entität ist, die von der Anwendung verwendet wird. Es sollte nur in den Schemas verwendet werden, um Felder automatisch zu inkrementieren.

+1

Schema-Standardwerte können nicht asynchron sein, dies funktioniert nicht. Wenn Sie auf der Seite mugoose [plugins] (http://plugins.mongoosejs.com/) nach "auto increment" suchen, finden Sie einige Optionen. – JohnnyHK

+0

@JohnnyHK Vielen Dank für Ihre Antwort. Die Plugins arbeiten auf Update-Event und etwas, das ich lieber vermeiden würde, Suche nach Autoinkrement brachte mich zum mongodb Artikel in erster Linie und npm installierbare Plugins für Mungo, die ereignisbasiert zu sein scheinen. – HMR

+0

Kannst du mir bitte sagen, welchen Ansatz du benutzt hast ?? Und wenn es mehrere gleichzeitige Anfragen gibt, wie geht Ihre Lösung damit um? –

Antwort

27

Hier ist ein Beispiel, wie Sie Autoinkrement-Feld in Mongoose implementieren können:

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(); 
    }); 
}); 
+0

Wo kann ich diese entitySchema.pre setzen ('save', Callback); wenn ich jedes meiner Modelle in separaten Dateien in einem Modellordner habe? –

+1

Sie können es gleich nach der Deklaration des Schemas in der gleichen Datei setzen – edtech

+0

Dies ist keine narrensichere Lösung, wenn es um gleichzeitige Anfragen geht - es ist möglich, dass Anfragen, die sehr nahe beieinander liegen, die gleiche Nummer in der "Sequenz haben " – realisation

24

Sie können mongoose-auto-increment Paket wie folgt verwenden:

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); 

Sie müssen nur die autoIncrement einmal initialisieren.

+2

Können Sie mir bitte sagen, wenn es mehrere gleichzeitige Anfragen gibt, wird Ihre Lösung funktionieren oder nicht? und wenn ja wie? –

4

Die am meisten gewählte Antwort funktioniert nicht. Dies ist das Update:

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; 
    }); 
}); 

Die Optionen Parameter das Ergebnis des Updates gibt und es ein neues Dokument erstellt, wenn sie noch nicht existiert. Sie können here das offizielle Dokument überprüfen.

Und wenn Sie eine sortierten Indexprüfung diese doc

-1

Die Antworten müssen scheinen, um die Sequenz zu erhöhen, selbst wenn das Dokument bereits ein _id Feld hat (Art, was auch immer). Dies ist der Fall, wenn Sie zum Aktualisieren eines vorhandenen Dokuments "speichern". Nein?

Wenn ich Recht habe, würden Sie next(), wenn this._id! == 0

Die Mungo docs sind nicht super klar darüber nennen. Wenn es ein Update Typ Abfrage intern tut, dann vor (‚retten‘ kann nicht aufgerufen werden.

KLARSTELLUNG

Es erscheint das ‚Speichern‘ pre-Methode in der Tat auf Updates genannt wird.

I don Ich glaube, Sie möchten Ihre Sequenz unnötigerweise inkrementieren.Es kostet Sie eine Anfrage und verschwendet die Sequenznummer.

0

Ich weiß, dass dies bereits viele Antworten war, aber ich würde meine Lösung teilen, die IMO kurz und einfach zu bedienen ist :

// 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(); 
    } 
}); 

Stellen Sie sicher, dass entitySchema._idtype:Number hat. Mungo-Version: 5.0.1.