في الآونة الأخيرة ، تم تحويل التطبيقان ، وحدثت سلسلة من المشكلات أثناء عملية الإطلاق (جزء منه كان سبب سوء فهم موضوعي)
دعونا أولاً نفهم الكائنات:
الطابع الزمني
الأرقام الأربعة الأولى هي طابع زمني UNIX ، فئة INT. نقوم باستخراج الأرقام الأربعة الأولى من الكائن في المثال أعلاه "4DF2DCEC" ، ثم تثبيتها في سداسي عشري إلى عشري: "1307761900". هذا الرقم هو الطابع الزمني. من أجل جعل التأثير أكثر وضوحًا ، نقوم بتحويل هذا الطابع الزمني إلى تنسيق الوقت الذي اعتدنا عليه (بالضبط إلى ثوان)
تاريخ $ -D '1970-01-01 UTC 1307761900 SEC' -U
السبت 11 يونيو 2011 03:11:40 UTC
تخفي البايتات الأربعة الأولى في الواقع وقت إنشاء المستندات ، والجدول الزمني في مقدمة الحرف ، مما يعني أنه سيتم فرز ObjectID تقريبًا عن طريق الإدراج ، والذي يلعب دورًا رائعًا في بعض الجوانب ، مثل تحسين كفاءة البحث كفهرس ، وما إلى ذلك. ميزة أخرى باستخدام الموقت يمكن أن تتم تحليلها عندما تم إدراج السجل من خلال السجل من خلال الكائن. هذا أيضًا يجيب على حقيقة أنه عندما ننشئ كائنات متعددة بطريقة سريعة ومستمرة ، سنجد أن الأرقام القليلة الأولى نادراً ما تجد تغييرات ، لأنها تستخدم الوقت الحالي. يشعر العديد من المستخدمين بالقلق من مزامنة وقت الخادم. في الواقع ، فإن القيمة الحقيقية لهذا الطابع الزمني ليست مهمة ، طالما أنها تتزايد باستمرار.
آلة
البايتات الثلاثة التالية هي 2CDCD2. هذه البايتات الثلاثة هي المعرفات الفريدة للمضيف حيث تقع ، وهي عمومًا قيمة التجزئة لاسم مضيف الجهاز. هذا يضمن أن المضيفين المختلفين يولدون قيم تجزئة الماكينة المختلفة والتأكد من عدم وجود تعارض في التوزيع. هذا هو السبب في أن السلاسل الموجودة في الكائنات التي تم إنشاؤها بواسطة نفس الجهاز هي نفسها تمامًا.
بيد
الجهاز أعلاه هو التأكد من أن الكائنات التي تم إنشاؤها على أجهزة مختلفة لا تتعارض ، في حين أن PID هو إنشاء كائنات لا تتعارض في عمليات MongoDB المختلفة على نفس الجهاز. البتتين التاليتين من 0936 هما معرفات العملية التي تولد كائنات.
زيادة
تضمن البايتات التسعة الأولى أن الكائنات التي تم إنشاؤها بواسطة آلات وعمليات مختلفة في ثانية واحدة لا تتعارض. البايتات الثلاثة التالية A8B817 هي عداد متزايد تلقائيًا لضمان عدم العثور على الكائنات التي تم إنشاؤها في نفس الثانية تعارضات ، مما يتيح الطاقة من 256 إلى 3 مساواة لتفرد سجلات 16777216.
تفرد الموضوع
قد تعتقد أنه إلى حد ما ، يمكن ضمان أن تكون فريدة من نوعها ، سواء على العميل أو على الخادم.
الاعتقاد الخاطئ 1. هل ترتيب المستند يتوافق مع أمر الإدراج؟
موقف واحد الخيوط
يمكن ضمان أن تكون الطابع الزمني والآلة و PID و Inc في ObjectID فريدة من نوعها لأنه على نفس الجهاز ونفس العملية.
هناك مشكلة هنا ، عمليات MongoDB متعددة الخيوط. A ، B ، C ... عندما تقوم العديد من المواضيع بإجراء العمليات داخل المتجر ، فليس من الممكن أن يكون هناك أي واحد يمكن أن يكون أمام الآخر ، لذلك سيكون خارج الترتيب.
الوضع متعدد المعايير أو متعددة الآلات أو متعددة العمليات
دعونا نلقي نظرة على Mache و PID في ObjectID التي لا يمكن ضمانها لتكون فريدة من نوعها. عندها ستكون البيانات أكثر خارج الترتيب.
حل:
نظرًا لأن البيانات الموجودة في المجموعة غير مرتبة (بما في ذلك المجموعة المغطاة) ، فإن أسهل طريقة هي فرز ObjectId.
هناك طريقتان لفرز ،
1. MongoDB بيان الاستعلام
jquery query = new query () ؛ if (id! = null) {jquery.addcriteria (معايير. } jQuery.with (sort (sort.direction.asc ، "_id")) ؛2.Java.Util.Priorityqueue
المقارنة <DbObject> المقارنة = المقارن الجديد <DbObject> () {Override public int (DbObject O1 ، dbObject O2) {return ((ObjectId) o1.get ("_ id")). compareto ((ObjectID) o2.get ("_ id")) ؛ }} ؛ priorityqueue <DbObject> Queue = new PriorityQueue <DbObject> (200 ، المقارنة) ؛الاعتقاد الخاطئ 2: عندما يكون لدى العديد من العملاء توافق عالٍ ، هل يمكن ضمان الطلب (بعد الفرز)؟
إذا تأكدت دائمًا من أن الكتابة أكبر بكثير من القراءة (أكثر من فترة ثانية واحدة) ، فلن يحدث هذا أبدًا.
لنلقي نظرة على المثال التالي
الآن انظر الرقم ، أخرج البيانات مرتين
أولاً
4DF2DCEC AAAA FFFF 36A8B813
4DF2DCEC AAAA EEEE 36A8B813
4DF2DCEC BBBB 1111 36A8B814
المرة الثانية
4DF2DCEC BBBB 1111 36A8B813
4DF2DCEC AAAA FFFF 36A8B814
4DF2DCEC AAAA EEEE 36A8B814
الآن إذا أخذت القيمة القصوى الأولى (4DF2DCEC BBBB 1111 36A8B814) للقيام بنتيجة الاستعلام التالية ، فسيتم تفويتها
العناصر الثلاثة للمرة الثانية ، لأن (4DF2DCEC BBBB 1111 36A8B814) أكبر من جميع السجلات التي تم أخذها في المرة الثانية.
هذا سوف يؤدي إلى فقدان البيانات.
حل:
نظرًا لأن الطابع الزمني لـ ObjectID يتم قطعه إلى ثوانٍ ، فإن الأرقام الأربعة الأولى من مشغل العداد هي أرقام الماكينة والعملية.
1. سجلات العملية قبل فترة زمنية معينة (أكثر من ثانية واحدة) ، حتى لو تسببت أرقام الماكينة والعملية في اضطراب ، فلن يكون هناك اضطراب قبل الفاصل الزمني.
2. إدراج نقطة واحدة ، يتم الآن الاستعلام عن عملية الإدراج التي تم توزيعها في الأصل على عدة نقاط ، بمقدار نقطة واحدة لضمان أن الجهاز ورقم العملية متماثلان ، ويتم استخدام مشغل العداد لجعل السجلات منظمة.
هنا ، استخدمنا الطريقة الأولى.
سوء الفهم 3. لا تضع dbobject_id باستخدام mongoDB لتعيين ObjectID؟
أثناء عملية إدخال MongoDB ، عندما يكون DBBASICOBJECT () جديدًا ، يرى الجميع أنه لا يتم ملء _ID ، ما لم يتم تعيين _ID يدويًا. فهل تم إعداده على الخادم؟
دعونا نلقي نظرة على رمز عملية الإدراج:
فئة التنفيذ
إدراج الكاتب العام (قائمة <DbObject> قائمة ، com.mongodb.writeconcern القلق ، dbencoder Encoder) {if (course == null) {رمي جديد غير electionArgumentException ("الكتابة لا يمكن أن تكون فارغة") ؛ } إرجاع إدراج (قائمة ، صواب ، قلق ، تشفير) ؛ }يمكنك أن ترى أنك بحاجة إلى إضافتها ، والافتراضي هو إضافة
insert الكاتب المحمية (قائمة <DbObject> ، يجب أن يكون Boolean apply ، com.mongodb.writeconcern ، dbencoder Encoder) {if (encoder == null) encoder = defaultDbenCoder.factory.create () ؛ if (willtrace ()) {for (dbObject o: list) {trace ("Save:" + _fullNamesPace + "" + json.serialize (o)) ؛ }} if (يجب (يجب أن يكون apply) {for (dbObject o: list) {application (o) ؛ _CheckObject (o ، خطأ ، خطأ) ؛ معرف الكائن = o.get ("_ id") ؛ if (id extryof ObjectId) {((objectId) id) .NotNew () ؛ }}} الكاتب الأخير = null ؛ int cur = 0 ؛ int maxSize = _mongo.getMaxBsonObjectSize () ؛ بينما (cur <list.size ()) {outMessage om = outMessage.insert (هذا ، التشفير ، القلق) ؛ لـ (؛ cur <list.size () ؛ cur ++) {dbObject o = list.get (cur) ؛ om.putObject (O) ؛ // حد إدراج الدُفعات هو 4 x maxbson على الخادم ، استخدم 2 x ليكون آمنًا إذا (om.size ()> 2 * maxSize) {cur ++ ؛ استراحة؛ }} last = _connector.say (_db ، om ، course) ؛ } العودة الأخيرة ؛ }إضافة عمليات ObjectID تلقائيًا
/** * Calls {link dbcollection#application (com.mongodb.dbobject ، boolean)} مع ضمان = true * param o <code> dbObject </code> والتي لإضافة الحقول * return كائن المعلمة المعدلة */كائن عام تطبيق (dbObject o) }/** * Calls {link dbCollection#doApply (com.mongodb.dbobject)} ، إضافة اختياريًا حقل _id تلقائي * @param jo لإضافة حقول إلى * param ضمان jouse juition) ما إذا كان لإضافة jouse jouse). id = jo.get ("_id") ؛ if (SupplyId && id == null) {id = objectId.get () ؛ jo.put ("_id" ، id) ؛ } doapply (Jo) ؛ معرف الإرجاع ؛ }كما ترون ، سيتم إضافة ObjectID تلقائيًا إلى حزمة برنامج تشغيل MongoDB.
طريقة الادخار
الكاتب العام Save (DbObject Jo ، WriteConcern Course) {if (checkReadOnly (true)) return null ؛ _CheckObject (Jo ، false ، false) ؛ كائن معرف = jo.get ("_id") ؛ if (id == null || (ideal exateOf ObjectID && ((ObjectID). id) .isnew ())) {if (id! = null && ide exatureof ObjectId) ((ObjectID). notnew () ؛ إذا (الاهتمام == فارغ) إدراج إدراج (JO) ؛ عودة أخرى إدراج (جو ، الاهتمام) ؛ } dbObject q = new basicdbobject () ؛ q.put ("_id" ، id) ؛ إذا (الاهتمام == null) تحديث إرجاع (Q ، Jo ، true ، false) ؛ آخر تحديث إرجاع (Q ، Jo ، True ، False ، Concert) ؛ }لتلخيص ، بشكل افتراضي ، يتم إنشاء ObjectID بواسطة العميل وليس بواسطة الخادم دون إعداد.
سوء الفهم 4. هل يمكن العثور على addlydify حقًا الحصول على متغيرات التقييم التلقائي؟
DbObject Update = New BasicDbObject ("$ inc" ، new BasicDbObject ("Counter" ، 1)) ؛ dbObject Query = New BasicDbobject ("_ id" ، المفتاح) ؛ DbObject Result = getMongotemplate (). getCollection (collectionName) .FindAndModify (Query ، Update) ؛ if (result == null) {dbObject doc = new basicdbobject () ؛ Doc.put ("Counter" ، 1L) ؛ doc.put ("_ id" ، مفتاح) ؛ // insert (collectionName ، doc) ؛ getMongotemplate (). حفظ (DOC ، CollectionName) ؛ العودة 1L ؛ } return (long) result.get ("counter") ؛سيتم كتابة متغيرات التلقائية باستخدام هذه الطريقة ، لكننا سنكتشف بعد التنفيذ.
FindAndModify Operation ، تنفيذ أولاً ، endr ثم تنفيذ التعديل ، لذلك عندما تكون النتيجة فارغة ، يجب إضافتها وإعادتها 0
ما سبق هو سوء الفهم وسلسلة من المشكلات الناجمة عن ObjectID في MongoDB الذي قدمه لك المحرر. آمل أن يكون ذلك مفيدًا لك. إذا كان لديك أي أسئلة ، فيرجى ترك رسالة لي وسوف يرد المحرر إليك في الوقت المناسب. شكرا جزيلا لدعمكم لموقع wulin.com!