سؤال

ما هي أفضل الممارسات لتخزين مجموعات متداخلة (مثل أشجار التعليقات) في منغ ولد؟

أعني، كل تعليق يمكن أن يكون لديه تعليق الوالدين وتعليقات الأطفال (إجابات).

تخزينها مثل هذا:

{
   title: "Hello",
   body: "Please comment me!",
   comments: [
        {
            author: "Peter",
            text: "Hi there",
            answers: [
                  {
                      author: "Peter",
                      text: "Hi there",
                      answers: [
                                 { author: "Ivan", text: "Hi there" },
                                 { author: "Nicholas", text: "Hi there" }
                      ]
                  },
                  { author: "Ivan", text: "Hi there" },
                  { author: "Nicholas", text: "Hi there" },
            ]
        },
        { author: "Ivan", text: "Hi there" },
        { author: "Nicholas", text: "Hi there" },
   ]
}

ليس رائعا، لأننا لا نستطيع، على سبيل المثال، طلب "كل الوظائف التي تعلق بها بيتر" دون خريطة / تقليل.

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

المحلول

أعتقد أنه لا يوجد حل مثالي - يعتمد على العمليات أكثر أهمية لتطبيقك. أعتقد أن Silicon Alley Insider Stores التعليقات المتداخلة مع Mongodb على سبيل المثال. هذا يجعل الاستعلام الذي ذكرته أكثر صعوبة.

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

ملاحظة واحدة أخرى - إذا كنت تتعامل مع مستند واحد، فربما يكون DB.Eval () ووزن أخف وزنا من الخريطة / الحد. $ حيث هو أيضا خيار، ولكن يمكن أن يكون بطيئا لذلك أنا أحب "قائمة المعلقين" الإضافية المذكورة أعلاه - ليس من السهل أيضا فهرس الصفيف أيضا (انظر "multikey" في المستندات).

أنظر أيضا:http://groups.google.com/group/mongodb-user/browse_thread/thread/df8250573c91f75a/e880d9c57e343b52؟lnk=gst&q=tries#e880d9c57e343b52.

نصائح أخرى

في الرابط من مشاركة DMONT DWIGHT Merriman باستخدام مفتاح المسار والقيام بتطابقات Regex

{
  path : "a.b.c.d.e.f"
}

وسيلة أخرى للقيام بذلك سيكون مع صفائف

{
  path : ["a", "b", "c", "d", "e", "f"]
}

db.test.ensureIndex({path: 1})

يجب أن تجعلها سريعة جدا.

إذا كان يمكن أن تكون كل عقدة فقط في مسار واحد، فلن تحتاج إلى أن تقلق بشأن المكان الذي يوجد به في القائمة

db.test.find({path: "a"})

سوف تجد جميع الأطفال من "A"

بدلا من أسماء المسار، ربما استخدم _ID من العقد.

تحديث

  • شيء واحد يجب توخي الحذر منه هو أن الفهرس يمكن أن يكون لديه صفيف واحد فقط فيه.
  • كن حذرا لاستخدام شرح على استفساراتك

    db.test.find.find ({path: {$ في: ["a"، "b"]})

يعطيك

 db.test.find({path: {$in: ["a", "b"]}}).explain()
{
        "cursor" : "BtreeCursor path_1 multi",
        "nscanned" : 2,
        "nscannedObjects" : 2,
        "n" : 1,
        "millis" : 0,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : true,
        "indexOnly" : false,
        "indexBounds" : {
                "path" : [
                        [
                                "a",
                                "a"
                        ],
                        [
                                "b",
                                "b"
                        ]
                ]
        }
}

لكن

 db.test.find({path: {$all: ["a", "b"]}}).explain()
{
        "cursor" : "BtreeCursor path_1",
        "nscanned" : 1,
        "nscannedObjects" : 1,
        "n" : 1,
        "millis" : 0,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : true,
        "indexOnly" : false,
        "indexBounds" : {
                "path" : [
                        [
                                "a",
                                "a"
                        ]
                ]
        }
}

يستخدم فقط العنصر الأول ثم يقوم بمسح جميع نتائج المطابقة ل B.
إذا كان عنصرك هو عنصر الجذر أو في معظم سجلاتك، فعليك إجراء فحص كامل من السجلات بدلا من استعلام مؤشر فعال.

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