2016-03-23 10 views
1

Ich bin ziemlich neu in MongoDb/Mongoose, mehr an SQL Server oder Oracle.Verhindern von doppelten Datensätzen in Mongoose

Ich habe ein ziemlich einfaches Schema für ein Ereignis.

EventSchema.add({ 
    pkey: { type: String, unique: true }, 
    device: { type: String, required: true }, 
    name: { type: String, required: true }, 
    owner: { type: String, required: true }, 
    description: { type: String, required: true }, 
}); 

Ich war bei Mongoose Indexes suchen, die es zu tun zwei Möglichkeiten zeigt, benutzte ich die Felddefinition.

Ich habe auch eine sehr einfache API, die einen POST akzeptiert und Aufrufe create für diese Sammlung, um den Datensatz einzufügen.

Ich schrieb einen Test, der überprüft, dass die Einfügung eines Datensatzes mit dem gleichen pkey nicht passieren sollte und dass das unique: true funktioniert. Ich habe bereits eine Reihe von Ereignissen, die ich in ein Array eingelesen habe, also poste ich einfach das erste dieser Ereignisse und sehe, was passiert, ich erwartete, dass Mongo DB den doppelten Schlüsselfehler E11000 werfen würde, aber das ist nicht geschehen.

var url = 'api/events'; 
var evt = JSON.parse(JSON.stringify(events[0])); 

// POST'ed new record won't have an _id yet 
delete evt._id; 

api.post(url) 
    .send(evt) 
    .end(err, res) { 
    err.should.exist; 
    err.code.should.equal(11000); 
    }); 

Der Test schlägt fehl, es gibt keinen Fehler und ein doppelter Datensatz wird eingefügt.

Wenn ich mir die Sammlung ansehe, kann ich zwei Datensätze sehen, beide mit der gleichen pKey (der ursprüngliche Datensatz und die Kopie, die ich für den Test gepostet habe). Ich merke, dass der zweite Datensatz das gleiche Erstellungsdatum wie das erste, aber ein späteres Änderungsdatum hat.

(Mongo mir nicht erwarten, dass die neueste modifizierte Version Rekord ??? zu verwenden, die URL anders und so ist die ID)

[ { _id: 2, 
    pkey: '6fea271282eb01467020ce70b5775319', 
    name: 'Event name 01', 
    owner: 'Test Owner', 
    device: 'Device X', 
    description: 'I have no idea what\'s happening', 
    __v: 0, 
    url: '/api/events/2', 
    modified: '2016-03-23T07:31:18.529Z', 
    created: '2016-03-23T07:31:18.470Z' }, 
    { _id: 1, 
    pkey: '6fea271282eb01467020ce70b5775319', 
    name: 'Event name 01', 
    owner: 'Test Owner', 
    device: 'Device X', 
    description: 'I have no idea what\'s happening', 
    __v: 0, 
    url: '/api/events/1', 
    modified: '2016-03-23T07:31:18.470Z', 
    created: '2016-03-23T07:31:18.470Z' } 
] 

ich angenommen hatte, dass einzigartig: true auf der Felddefinition sagte Mongo db dass das was du wolltest und mongo das für dich bei speichern erzwang, oder vielleicht habe ich einfach etwas falsch verstanden ...

In SQL-Termini erstellst du einen Schlüssel, der in der URL-Suche verwendet werden kann, aber du kannst einen einzigartigen zusammengesetzten Index erstellen , um doppelte Einfügungen zu vermeiden. Ich muss in der Lage sein zu definieren, welche Felder in einem Ereignis den Datensatz eindeutig machen, da der Übermittler eines Formulars auf einem Formulardaten-POST nicht den nächsten verfügbaren _id-Wert hat, aber die _id verwendet (erledigt von "mongoose-auto-increment") so), dass die Verwendung des URL aus anderen Teilen der App sauber ist, wie

/events/1 

und nicht ein komplettes Chaos der Verbindung Werte wie

/events/Event%20name%2001%5fDevice%20X%5fTest%20Owner 

bin ich Codierung bis beginnen gerade über die Ich habe jetzt einen einfachen Test gegen diese einzelne Zeichenkette geschrieben, aber das reale Schema hat ein paar mehr Felder und wird eine Kombination von ihnen für die Eindeutigkeit verwenden, ich möchte wirklich die ersten Tests erhalten Ich arbeite, bevor ich anfange, weitere Tests, mehr Felder und mehr Code hinzuzufügen.

Gibt es etwas, das ich tun sollte, um sicherzustellen, dass der zweite Datensatz nicht tatsächlich eingefügt wird?

+0

Sie sollten wahrscheinlich etwas gelesen haben und festgestellt haben, dass das "madatorische" '_id' Feld tatsächlich der Primärschlüssel ist. Sie müssen hier etwas getan haben, da numerische Werte darin enthalten sind, die nicht die Standardeinstellung wären (vielleicht importierter numerischer Primärschlüssel). Und wenn Sie tatsächlich einen anderen Wert haben, der ein "einzigartiger Primärschlüssel" ist, dann sollten Sie ihn stattdessen in _id setzen. Wenig Lesen würde viel Ärger sparen. –

+1

gehe ein paar Sachen lesen, nicht so hilfreich ..., habe ich "mongoose-auto-increment" eingeschlossen, was scheinbar die _id erzeugt und sie um 1 auf jeden Speicherstand erhöhen lässt. _id kann für/events /: id eindeutig und nützlich sein, aber dies macht den Datensatz nicht eindeutig. Dies wird durch eine zusammengesetzte Kombination von Feldern des Ereignisses bestimmt (die hinzugefügt werden sollen). Ich wollte sehen, ob es mit einem einfacheren Test auf einem Feld des Schemas funktionieren würde, bevor ich anfing, dem Index mehrere Werte hinzuzufügen und das Ganze zu kodieren. Ein zusammengesetzter Schlüsselwert gibt das Ereignis/{: horible_key} in der URL an. –

Antwort

0

OK es sieht so aus, es hat etwas mit dem Index nicht mit der Zeit zu tun, um zu aktualisieren, bevor der zweite Einsatz gebucht wird (da es nur 9ms zwischen ihnen in meinem Test-Suite ist).

  • Bedürfnis, etwas über Einsätze für „index“
  • Bedürfnisse sein API Seite, da nicht alle Benutzer der API sind Web-Anwendungen

Ich fand auch einige andere SO Artikel zu Einschränkungen warten zu tun :

mongoose unique: true not work

Unique index not working with Mongoose/MongoDB

MongoDB/Mongoose unique constraint on Date field

0

add:

EventSchema.index({ pkey: 1 }, { unique: true }); 
+0

OK - das habe ich gemacht, aber die Ergebnisse sind gleich. Ich bekomme zwei Datensätze mit identischen pkey Werten ... Als schnellen Test habe ich auch Ihren Vorschlag ausprobiert und entfernt das einzigartige aus der Felddefinition auch (war nicht sicher, ob du wolltest, dass ich das ersetze), aber das fügt auch zwei Datensätze ein ... :( –

0

Ich glaube, dass Sie nach dem Einfügen einiger Datensätze in db eine eindeutige Indizierung (auf Schemaebene) durchgeführt haben.

Sie bitte das folgende Schritte zur Vermeidung von Duplikaten folgen -

1) Drop Ihre db:

$ Mongo

> use <db-name>; 

> db.dropDatabase(); 

2) jetzt tun Indizierung auf Schemaebene oder db Ebene

var EventSchema = new mongoose.Schema({ 
     pkey: { type: String, unique: true }, 
     device: { type: String, required: true }, 
     name: { type: String, required: true }, 
     owner: { type: String, required: true }, 
     description: { type: String, required: true }, 
    }); 

wird es doppelte Einfügung von Einträgen mit demselben pKey-Wert vermeiden.

und zum Sicherstellen des Indexes den Befehl db.db_name.getIndexes() verwenden.

hoffe das hilft.

Verwandte Themen