يعود MongoDB السلاسل ذات الرسملة أولاً عند الفرز

StackOverflow https://stackoverflow.com/questions/19855147

  •  29-07-2022
  •  | 
  •  

سؤال

عندما حاولت فرز مجموعة مجموعة سلسلة (هنا Title) ، فرز لا يعمل كما هو متوقع. من فضلك، انظر بالأسفل:

db.SomeCollection.find().limit(50).sort({ "Title" : -1 });

ترتيب النتيجة الفعلي

  • "العنوان": "كتاب الطلاب geog.3"
  • "العنوان": "كتاب الطلاب Geog.2"
  • "العنوان": "كتاب الطلاب geog.1"
  • "العنوان": "زوي وسويفت"
  • "العنوان":
  • "العنوان": "Zip at the Supermarket"

أمر النتيجة المتوقع

  • "العنوان": "زوي وسويفت"
  • "العنوان":
  • "العنوان": "Zip at the Supermarket"
  • "العنوان": "كتاب الطلاب geog.3"
  • "العنوان": "كتاب الطلاب Geog.2"
  • "العنوان": "كتاب الطلاب geog.1"

تحدث نفس المشكلات عندما حاولت فرز حقل التاريخ.

أي اقتراحات؟

هل كانت مفيدة؟

المحلول

تحديث: الإصدار 3.4 لديه الفهارس غير الحساسة للحالة

هذه قضية معروفة. MongoDB لا يدعم الفرز المعجمي للسلاسل (جيرا: ترتيب معجم سلسلة). يجب عليك فرز النتائج في رمز التطبيق الخاص بك ، أو الفرز باستخدام حقل رقمي. يجب أن يحدد حقول التاريخ بشكل موثوق. هل يمكنك إعطاء مثال لا يعمل فيه الفرز حسب التاريخ؟

نصائح أخرى

ما الذي يفاجئك بالضبط؟

إنه يعتمد على عرض التمثيل العددي للرمز. إذا كنت ستنظر هنا (أعلم أن سلسلة MongoDB Stores في UTF-8 ، لذلك هذا فقط لغرض تعليمي). سترى أن الحروف العلوية لها أرقام مقابلة أقل ثم الحروف السفلية. وبالتالي سوف يذهبون في المقدمة.

لا يمكن لـ MongoDB فرز الحروف بناءً على التوطين أو حالة غير حساسة.

في حالتك g بعد ذلك Z, ، لذلك يذهب أولا (الفرز في تناقص الترتيب). وثم 3 لديه رقم المقابل أعلى بعد ذلك 2 و 1. لذلك كل شيء في الأساس صحيح.

إذا كنت تستخدم التجميع ، فمن الممكن الإخراج المتوقع ، انظر أدناه:

    db.collection.aggregate([
    { 
        "$project": {
           "Title": 1,        
           "output": { "$toLower": "$Title" }       
        }},
        { "$sort": {  "output":-1 } },
        {"$project": {"Title": 1, "_id":0}}
    ])


سوف يعطيك الناتج المتوقع على النحو التالي:

    {
        "result" : [ 
            {
                "Title" : "Zoe and Swift"
            }, 
            {
                "Title" : "Zip at the Theme Park"
            }, 
            {
                "Title" : "Zip at the Supermarket"
            }, 
            {
                "Title" : "geog.3 students' book"
            }, 
            {
                "Title" : "geog.2 students' book"
            }, 
            {
                "Title" : "geog.1 students' book"
            }
        ],
        "ok" : 1
    }

بدءًا من التواريخ التي لا تُفرز بشكل صحيح ....

إذا كنت تقوم بتخزين موعد ك string, ، يجب أن تكون قابلة للفرز كسلسلة. انها بسيطة جدا:

2013-11-08  // yyyy-mm-dd (the dashes would be optional)

طالما أن كل قطعة من سلسلة التاريخ مبطنة 0 بشكل صحيح ، سيتم فرز السلاسل بشكل طبيعي والطريقة التي تتوقعها.

يتم تخزين بوقت موعد كامل في UTC عادة:

2013-11-23T10:46:01.914Z

لكنني أقترح عليك أيضًا بدلاً من تخزين قيمة التاريخ كسلسلة ، فأنت تفكر فيما إذا كان استخدام تاريخ MongoDB الأصلي سيكون أكثر منطقية (المرجعي). إذا نظرت إلى إطار تجميع MongoDB ، فستجد أن هناك الكثير المهام يمكن أن تعالج هذه التواريخ ، في حين أن السلسلة محدودة للغاية.

فيما يتعلق بفرز السلسلة ، تمت الإشارة إلى أنه يتم فرزه مثل الكمبيوتر يخزن البيانات بدلاً من الطريقة التي ستقوم بفرزها كشخص. إذا كنت تفكر في تخزين السلسلة كتمثيل ASCII/UTF-8 ، فيجب أن ترى لماذا يعمل الفرز كما هو:

Zoe = [90, 111, 101]
geo = [103, 101, 111]

إذا كنت ترغب في فرز أولئك في ترتيب تنازلي كما هو محدد ، فيجب أن ترى كيف "geo"تمثيل البايت الداخلي أكبر من تمثيل السلسلة "Zoe" (مع 103 فرز أعلى من 90 في هذه الحالة).

عادةً ما تكون التوصية عند استخدام MongoDB هي تخزين الأوتار مرتين إذا كنت بحاجة إلى فرز سلسلة تحتوي على حالة مختلطة:

  1. السلسلة الأصلية ("Title")
  2. كسلسلة طبيعية. ربما على سبيل المثال ، ربما يتم تحويل كل شيء "صغير" مع أحرف معلمة أيضًا إلى حرف مشترك. لذا ، سينتهي بك الأمر بحقل جديد يدعى "SortedTitle" على سبيل المثال ، وسيستخدم الرمز الخاص بك ذلك لفرز ، ولكن عرض الفعلي "Title" للمستخدمين.

إذا كنت تفعل في ROR و mongomapper ، فاتبع الخطوات أدناه:

لقد أخذت اسم النموذج الخاص بي ABC ونتيجة جلب للعنوان.

@test_abc_details_array_full=Abc.collection.aggregate([

     {"$project"=> {
       "Title"=> 1,        
       "output"=> { "$toLower"=> "$Title" }       
    }},
    { "$sort"=> {  "output"=>1 } },        
    {"$project"=> {Title: 1, _id:0}},

  ]); 
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top