Vor kurzem wurden die beiden Anwendungen transformiert, und während des Startprozesses trat eine Reihe von Problemen auf (der durch das objekte Missverständnis des Missverständnisses verursacht wurde)
Lassen Sie uns zunächst die ObjektID verstehen:
Zeitstempel
Die ersten 4 Ziffern sind ein Unix -Zeitstempel, eine Int -Kategorie. Wir extrahieren die ersten 4 Ziffern der ObjektID im obigen Beispiel "4DF2DCEC" und installieren sie dann in Hexadezimal in Dezimal: "1307761900". Diese Zahl ist ein Zeitstempel. Um den Effekt offensichtlicher zu machen, wandeln wir diesen Zeitstempel in das Zeitformat um, an das wir gewohnt sind (genau bis Sekunden),
$ Date -d '1970-01-01 UTC 1307761900 Sek' -U -u
Samstag, 11. Juni 2011 03:11:40 UTC
Die ersten 4 Bytes verbergen tatsächlich die Zeit der Dokumentenerstellung, und der Zeitstempel befindet sich an der Vorderseite des Charakters, was bedeutet, dass die ObjektID grob durch Einfügen sortiert wird, was in einigen Aspekten eine große Rolle spielt, wie z. Dies beantwortet auch die Realität, dass wir, wenn wir auf schnelle und kontinuierliche Weise mehrere ObjektIDs erstellen, feststellen, dass die ersten Ziffern selten Änderungen finden, da sie die aktuelle Zeit nutzen. Viele Benutzer sind besorgt über die Synchronisierung der Serverzeit. Tatsächlich ist der wahre Wert dieses Zeitstempels nicht wichtig, solange er ständig zunimmt.
Maschine
Die nächsten drei Bytes sind 2CDCD2. Diese drei Bytes sind die eindeutigen Kennungen des Hosts, in dem sie sich befinden, und im Allgemeinen der Hash -Wert des Maschinen -Host -Namens. Dies stellt sicher, dass verschiedene Hosts unterschiedliche Maschinen -Hash -Werte erzeugen und sicherstellen, dass die Verteilung keinen Konflikt gibt. Aus diesem Grund sind die von derselben Maschine erzeugten Saiten in der ObjektID genau gleich.
PID
Die obige Maschine soll sicherstellen, dass die auf verschiedenen Maschinen erzeugten ObjektIDs nicht konflikt, während die PID Objekte erzeugen soll, die nicht in verschiedenen MongoDB -Prozessen auf derselben Maschine konflikt. Die nächsten beiden Bits von 0936 sind die Prozesskennung, die Objekte erzeugen.
Inkrement
Die ersten neun Bytes stellen sicher, dass Objekte, die von verschiedenen Maschinen und Prozessen innerhalb einer Sekunde erzeugt werden, nicht konflikt. Die nächsten drei Bytes A8B817 sind ein automatisch erhöhter Zähler, um sicherzustellen, dass Objekte, die in derselben Sekunde erzeugt werden, keine Konflikte finden, wodurch 256 bis 3. Macht der Einzigartigkeit von 16777216 Aufzeichnungen entspricht.
Objektid -Einzigartigkeit
Sie denken vielleicht, dass es in gewissem Maße garantiert einzigartig ist, sei es auf dem Client oder auf dem Server.
Missverständnis 1. Stimmt die Dokumentreihenfolge mit der Einfügungsreihenfolge überein?
Einzelfadensituation
Der Zeitstempel, die Maschine, PID und Inc in ObjectID kann garantiert als einzigartig sind, da auf derselben Maschine und im gleichen Prozess.
Hier gibt es ein Problem, MongoDB-Operationen sind multi-thread. A, B, C ... Wenn mehrere Threads im Ladenbetrieb führen, ist nicht garantiert, welches vor dem anderen sein kann, sodass es nicht in Ordnung ist.
Multithread-, Multi-Machine- oder Mehrprozess-Situation
Schauen wir uns die Mache und die PID in ObjectID an, die nicht garantiert sind, dass sie einzigartig sind. Dann sind die Daten noch mehr nicht in Ordnung.
Lösung:
Da die Daten in der Sammlung nicht ordnungsgemäß sind (einschließlich der Kollektion des Kapitels), besteht der einfachste Weg, die ObjektID zu sortieren.
Es gibt zwei Möglichkeiten zu sortieren,
1.MongoDB -Abfrageanweisung
JQuery query = new query (); if (id! } jQuery.with (neue sort (sort.direction.asc, "_id"));
2.Java.util.Priorityqueue
Vergleicher <dbObject> vergleicher = neuer vergleicher <dbObject> () {@Override public int compare (dbObject o1, dbObject o2) {return ((ObjectID) o1.get ("_ id")). Vergleiche ((Objekt) o2.get ("_ id"); }}; PriorityQueue <DBObject> queue = new PriorityQueue <DBObject> (200, Comparator);Missverständnis 2: Wenn mehrere Clients eine hohe Parallelität haben, kann die Bestellung garantiert werden (nach Sortieren)?
Wenn Sie immer sicherstellen, dass das Schreiben viel größer ist als die Anzeige (mehr als ein zweites Intervall), wird dies niemals aus der Reihenfolge geschehen.
Schauen wir uns das folgende Beispiel an
Sehen Sie nun die Abbildung an, nehmen Sie die Daten zweimal heraus
Erste
4DF2DCEC AAAA FFFF 36A8B813
4DF2DCEC AAAA EEEE 36A8B813
4DF2DCEC BBBB 1111 36A8B814
Das zweite Mal
4DF2DCEC BBBB 1111 36A8B813
4DF2DCEC AAAA FFFF 36A8B814
4DF2DCEC AAAA EEEE 36A8B814
Wenn Sie nun den ersten Maximalwert (4DF2DCEC BBBB 1111 36A8B814) nehmen, um das nächste Abfrageergebnis zu erzielen, wird es übersehen
Die drei Elemente des zweiten Males, da (4DF2DCEC BBBB 1111 36A8B814) größer sind als alle Datensätze, die beim zweiten Mal aufgenommen wurden.
Dies wird zu Datenverlust führen.
Lösung:
Da der Zeitstempel von ObjectID auf Sekunden abgeschnitten wird, sind die ersten vier Ziffern des Zählerbetreibers die Maschine und die Prozesszahlen.
1. Verarbeitung Aufzeichnungen vor einem bestimmten Zeitintervall (mehr als eine Sekunde), so dass selbst wenn die Maschine und die Prozesszahlen eine Störung verursachen, keine Störung vor dem Intervall vorliegt.
2. Ein-Punkte-Insertion, der ursprünglich auf mehrere Punkte verteilte Insertionsvorgang, wird nun von einem Punkt abgefragt, um sicherzustellen, dass die Maschine und die Prozessnummer gleich sind, und der Zählerbetreiber wird verwendet, um die Datensätze ordentlich zu machen.
Hier haben wir die erste Methode verwendet.
Missverständnis 3. Setzen Sie dBObject_id nicht mit MongoDB, um ObjektID festzulegen?
Während der MongoDB -Insertionsoperation, wenn neue dbbasicObject () (), sieht jeder, dass _id nicht ausgefüllt ist, es sei denn, _id wird manuell eingestellt. Ist es also auf dem Server eingerichtet?
Schauen wir uns den Code für den Einfügungsvorgang an:
Implementierungsklasse
public writerSult Insert (Liste <DBObject> List, comongodb.WriteConcOncern, DbenCoder -Encoder) {if (bedenken == null) {werfen Sie eine neue IllegalArgumentException ("Schreiben Sie nicht null"); } return Insert (Liste, True, Bedenken, Encoder); }Sie können sehen, dass Sie hinzufügen müssen. Die Standardeinstellung ist hinzuzufügen
Protected WriterSult Insert (Liste <DBObject> Liste, Boolean sollte angewendet, com.Mongodb.writeConcern Concern, DbenCoder -Encoder) {if (cnoder == null) cnoder = defaultDBencoder.factory.craate (); if (Willtrace ()) {für (dBObject O: list) {trece ("speichern:" + _fullnamespace + "" + json.serialize (o)); }} if (sollte (sollte apply) {for (dBObject o: list) {anwenden (o); _checkObject (o, falsch, falsch); Objekt id = o.get ("_ id"); if (id instanceof objectID) {((objectId) id) .notNoTNew (); }}} Writersult last = null; int cur = 0; int maxSize = _mongo.getMaxbsonObjectSize (); while (cur <list.size ()) {outMessage om = outmessage.insert (this, codierer, beunruhigend); für (; cur <list.size (); cur ++) {dBObject o = list.get (cur); om.putObject (o); // Begrenzung für den Batch -Einsatz beträgt 4 x maxbson auf dem Server. Verwenden Sie 2 x, um sicher zu sein, wenn (om.size ()> 2 * maxSize) {cur ++; brechen; }} last = _connector.say (_db, om, beunruhigend); } kehren zuletzt zurück; }Fügen Sie automatisch ObjektID -Vorgänge hinzu
/** * Aufrufe {@link dbcollection#anwenden (com.mongodb.dbobject, boolean)} mit safeId = true * @param o <Code> dBObject </code>, an dem Felder hinzugefügt werden soll * @return das geänderte Parameter -Objekt */öffentlich (dBobject o) {return apell (o true); } /** * calls {@link DBCollection#doapply(com.mongodb.DBObject)}, optionally adding an automatic _id field * @param jo object to add fields to * @param ensureID whether to add an <code>_id</code> field * @return the modified object <code>o</code> */ public Object apply( DBObject jo , boolean ensureID ){ Object id = jo.get ("_id"); if (sicher && id == null) {id = objectId.get (); jo.put ("_id", id); } doapply (jo); Rückgabe -ID; }Wie Sie sehen können, wird ObjectID dem MongoDB -Treiberpaket automatisch hinzugefügt.
Die Methode des Speicherns
public writersult save (dbobject jo, writeconcern beunruhigung) {if (checkReadonly (wahr)) null; _checkObject (jo, falsch, falsch); Objekt id = jo.get ("_id"); if (id == null || (id instanceof objectId && ((objectId) id) .isNew ())) {if (id! if (bedenken == null) return Insert (jo); sonst return Insert (Jo, Bedenken); } DBObject q = new BasicDBObject (); Q.put ("_id", id); if (bedenken == null) return update (q, jo, true, false); sonst Rückgabe -Update (Q, Jo, True, False, Sorge); }Zusammenfassend wird ObjectID vom Client und nicht vom Server ohne Einstellung generiert.
Missverständnisse 4. Kann FindandModify wirklich automatische Inkrementvariablen finden?
DBObject update = new BasicDBObject ("$ Inc", New BasicDBObject ("Zähler", 1)); DBObject query = new BasicDBObject ("_ id", Schlüssel); DBObject result = getMongotemplate (). GetCollection (CollectionName) .FindandModify (Abfrage, Update); if (result == null) {dbObject doc = new BasicDBObject (); doc.put ("counter", 1l); doc.put ("_ id", key); // einfügen (CollectionName, doc); getMongotemplate (). Save (doc, collectionName); Rückkehr 1l; } return (long) result.get ("counter");Das Erhalten von automatischen Variablen wird mit dieser Methode geschrieben, wir werden es jedoch nach der Ausführung herausfinden.
FindandModify -Operation führen Sie zuerst Find und dann ändern Sie Änderungen aus. Wenn das Ergebnis null ist, sollte sie hinzugefügt und 0 zurückgegeben werden
Das obige sind die Missverständnisse und eine Reihe von Problemen, die von ObjectID in MongoDB verursacht wurden, die der Editor Ihnen vorgestellt hat. Ich hoffe, es wird Ihnen hilfreich sein. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht und der Editor wird Ihnen rechtzeitig antworten. Vielen Dank für Ihre Unterstützung auf der Wulin.com -Website!