2016-08-09 23 views
3

Ich habe den folgenden Code:

db.foo.insert([{_pos:1,b:12},{_pos:2,a:23},{_pos:3,c:12}]) 
db.foo.createIndex({ "_pos" : 1 }, { unique: true }) 
db.foo.update({}, { "$inc" : {"_pos" : 1} }, { multi : true }) 

Die letzte Zeile gibt mir die folgende Fehlermeldung:

E11000 duplicate key error index: JsonTableTemp.foo.$_pos_1 dup key: { : 2.0 }

$isolated auf die Abfrage Hinzufügen hilft nicht .

Wie kann ich das Feld _pos inkrementieren, ohne zuerst den Index zu löschen?

Ich benutze mongodb 3.2.6

+0

Ich habe es gerade versucht und der createIndex hat den Fehler für mich geworfen. Das Update funktionierte perfekt, als ich {unique: true} aus der zweiten Zeile entfernte. – dyouberg

+0

@dyouberg: Warum scheiterte createIndex? Welche mongodb Version verwendest du? – Dreamcooled

+0

Mongo Version 3.2.0 > db.foo.createIndex ({ "_pos": 1}, {einzigartig: true}) { \t "ok": 0, \t "errmsg": „E11000 Schlüsselfehler duplizieren Sammlung: test.foo Index: _pos_1 dup Schlüssel: {: 1.0} ", \t" Code ": 11000 } – dyouberg

Antwort

2

Ok, ich habe es ...

Da Sie die Indizes einzigartig machen - die Werte immer nicht den gleichen Wert teilen. Die Werte sind [1,2,3]. Die increment ist eine atomare Operation von MongoDB, so dass sie nacheinander auftreten ... Zuerst wäre [2,2,3] dann [2,3,3] dann schließlich [2,3,4].

Um dies zu beweisen ... einfach die Werte auf [3,2,1] umkehren, um zu beginnen.

> db.foo5.insert([{_pos:3,b:12},{_pos:2,a:23},{_pos:1,c:12}]) 
BulkWriteResult({ 
    "writeErrors" : [ ], 
    "writeConcernErrors" : [ ], 
    "nInserted" : 3, 
    "nUpserted" : 0, 
    "nMatched" : 0, 
    "nModified" : 0, 
    "nRemoved" : 0, 
    "upserted" : [ ] 
}) 
> db.foo5.createIndex({ "_pos" : 1 }, { unique: true }) 
{ 
    "createdCollectionAutomatically" : false, 
    "numIndexesBefore" : 1, 
    "numIndexesAfter" : 2, 
    "ok" : 1 
} 
> db.foo5.find() 
{ "_id" : ObjectId("57a9f76cb28f053d25a821a5"), "_pos" : 3, "b" : 12 } 
{ "_id" : ObjectId("57a9f76cb28f053d25a821a6"), "_pos" : 2, "a" : 23 } 
{ "_id" : ObjectId("57a9f76cb28f053d25a821a7"), "_pos" : 1, "c" : 12 } 
> db.foo5.update({}, { "$inc" : {"_pos" : 1} }, { multi : true }) 
WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 }) 
> db.foo5.find() 
{ "_id" : ObjectId("57a9f76cb28f053d25a821a5"), "_pos" : 4, "b" : 12 } 
{ "_id" : ObjectId("57a9f76cb28f053d25a821a6"), "_pos" : 3, "a" : 23 } 
{ "_id" : ObjectId("57a9f76cb28f053d25a821a7"), "_pos" : 2, "c" : 12 } 
+0

Ja, ich habe das auch herausgefunden, aber eine Änderung der Reihenfolge ist für mich keine wirkliche Option. Deshalb habe ich gefragt: Wie kann ich das Feld _pos ** erhöhen, ohne vorher den Index fallen zu lassen? – Dreamcooled

+0

Ja, es sieht so aus, als ob entweder der eindeutige Teil des Indexes entfernt werden müsste oder eine Form der Steuerung des gemeinsamen Zugriffs auf den Vorgang erforderlich wäre. Ich habe auch die $ isoliert versucht und konnte das nicht zur Arbeit bekommen. Gibt es einen Grund, warum Ihr Index eindeutig sein muss? – dyouberg

+0

Wenn ich das einzigartige Teil entferne, muss ich die Einzigartigkeit clientseitig sicherstellen, was sich falsch anfühlt. Ich denke auch, dass ein einzigartiger Index einige Operationen im Vergleich zu einem normalen Index beschleunigen wird. – Dreamcooled

Verwandte Themen