2009-12-05 13 views
7

MongoDB में नेस्टेड सेट (टिप्पणियों के पेड़ों की तरह) स्टोर करने के लिए सबसे अच्छा प्रथा क्या है?MongoDB नेस्टेड सेट

मेरा मतलब है, प्रत्येक टिप्पणी में माता-पिता की टिप्पणी और बच्चों-टिप्पणियां (उत्तर) हो सकती हैं।

उन्हें इस तरह भंडारण:

{ 
    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" }, 
    ] 
} 

, शांत नहीं है, क्योंकि हम नहीं, उदाहरण के लिए, "सभी पोस्ट जो पीटर द्वारा टिप्पणी की" बिना नक्शा के लिए पूछ सकते/कम।

उत्तर

3

मुझे लगता है कि कोई सही समाधान नहीं है - यह निर्भर करता है कि आपके ऐप के लिए कौन से ऑपरेशन अधिक महत्वपूर्ण हैं। मेरा मानना ​​है कि सिलिकॉन एली इनसाइडर उदाहरण के लिए मोंगोडीबी के साथ घोंसला वाली टिप्पणियां संग्रहीत करता है। यह उस प्रश्न को बनाता है जिसका आप उल्लेख करते हैं।

एक विकल्प पोस्ट में शीर्ष-स्तर पर स्टोर में सभी टिप्पणियों की एक सूची है। इसके बारे में सोचें कि denormalized डेटा के रूप में। फिर कोई आसानी से सभी पोस्ट ढूंढ सकता है जिसमें एक निश्चित टिप्पणीकर्ता शामिल होता है। फिर ड्रिल करने के लिए, आप नेस्टेड पोस्ट जानकारी को अंदर लाने के लिए मानचित्र/कमी या db.eval() का उपयोग करें।

एक अन्य नोट - यदि आप एक दस्तावेज़ से निपट रहे हैं, db.eval() शायद नक्शा/कम से कम हल्का वजन है। $ जहां एक विकल्प भी है लेकिन धीमा हो सकता है इसलिए मुझे उपरोक्त वर्णित अतिरिक्त 'कमेंटर्स की सूची' पसंद है - न कि उस सरणी को भी इंडेक्स करना भी आसान है (दस्तावेज़ों में 'मल्टीकी' देखें)।

यह भी देखें: http://groups.google.com/group/mongodb-user/browse_thread/thread/df8250573c91f75a/e880d9c57e343b52?lnk=gst&q=trees#e880d9c57e343b52

2

dm पद ड्वाइट मेरीमैन से लिंक में एक पथ कुंजी का उपयोग और यह करने के लिए रेगुलर एक्सप्रेशन से एक और तरीका है मैच

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

कर उल्लेख सरणियों के साथ होगा

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

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

जो इसे बहुत तेज़ बनाना चाहिए।

यदि प्रत्येक नोड केवल एक ही रास्ते में हो सकता है तो आप जहां यह सूची

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

में स्थित है के बारे में चिंता करने की ज़रूरत नहीं होगी "एक"

के सभी बच्चों मिलेगा पथ नामों के बजाय मैं शायद नोड्स के _id का उपयोग करूंगा। के सावधान रहने की

अद्यतन

  • एक बात यह है कि एक सूचकांक केवल उस में एक सरणी हो सकता है।
  • अपने प्रश्नों पर व्याख्या करने के लिए सावधान रहें

    db.test।लगता है ({पथ: {$ में: [ "एक", "बी"]})

आप

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" 
         ] 
       ] 
     } 
} 

केवल पहला तत्व का उपयोग करता है और देता है फिर बी के लिए सभी मिलान परिणामों को स्कैन करता है।
यदि आपका मूल तत्व है या आपके अधिकांश रिकॉर्ड में है तो आप एक कुशल इंडेक्स क्वेरी के बजाय रिकॉर्ड्स का लगभग पूरा स्कैन कर रहे हैं।

संबंधित मुद्दे