MongoDB
 sql >> डेटाबेस >  >> NoSQL >> MongoDB

एक कैप्ड संग्रह का उपयोग किए बिना MongoDB में दस्तावेज़ों के ऑर्डर किए गए सेट को कैसे स्टोर करें

आपकी आवश्यकता के आधार पर, दृष्टिकोणों में से एक यह हो सकता है कि आप अपने स्कीमा को इस तरह से डिज़ाइन करें कि प्रत्येक दस्तावेज़ में क्षमता हो एक से अधिक दस्तावेज़ रखने और अपने आप में एक कैप्ड कंटेनर . के रूप में कार्य करने के लिए ।

{
  "_id":Number,
  "doc":Array
}

संग्रह का प्रत्येक दस्तावेज़ कैप्ड कंटेनर . के रूप में कार्य करेगा , और दस्तावेज़ों को doc . में सरणी के रूप में संग्रहीत किया जाएगा खेत। doc फ़ील्ड एक सरणी होने के कारण, सम्मिलन के क्रम को बनाए रखेगा। आप दस्तावेज़ों की संख्या को n तक सीमित कर सकते हैं . तो _id प्रत्येक कंटेनर दस्तावेज़ का क्षेत्र n . द्वारा वृद्धिशील होगा , एक कंटेनर दस्तावेज़ में रखे जा सकने वाले दस्तावेज़ों की संख्या को दर्शाता है।

ऐसा करने से आप से बचें extra fields जोड़ना दस्तावेज़ के लिए, extra indices , unnecessary sorts

पहला रिकॉर्ड सम्मिलित करना

यानी जब संग्रह खाली हो।

var record = {"name" : "first"};
db.col.insert({"_id":0,"doc":[record]});

बाद के रिकॉर्ड सम्मिलित करना

  • अंतिम कंटेनर दस्तावेज़ के _id की पहचान करें , और number उसके पास जो दस्तावेज हैं।
  • यदि उसके पास जितने दस्तावेज़ हैं, वह n . से कम है , फिर अपडेट करें नए दस्तावेज़ के साथ कंटेनर दस्तावेज़, अन्यथा बनाएं एक नया कंटेनरदस्तावेज़।

मान लें, कि प्रत्येक container document 5 पकड़ सकते हैं अधिक से अधिक दस्तावेज़, और हम एक नया दस्तावेज़ सम्मिलित करना चाहते हैं।

var record = {"name" : "newlyAdded"};

// using aggregation, get the _id of the last inserted container, and the 
// number of record it currently holds.
db.col.aggregate( [ {
    $group : {
        "_id" : null,
        "max" : {
            $max : "$_id"
        },
        "lastDocSize" : {
            $last : "$doc"
        }
    }
}, {
    $project : {
        "currentMaxId" : "$max",
        "capSize" : {
            $size : "$lastDocSize"
        },
        "_id" : 0
    }
// once obtained, check if you need to update the last container or 
// create a new container and insert the document in it.
} ]).forEach( function(check) {
    if (check.capSize < 5) {
        print("updating");
        // UPDATE
        db.col.update( {
            "_id" : check.currentMaxId
        }, {
            $push : {
                "doc" : record
            }
        });
    } else {
        print("inserting");
        //insert
        db.col.insert( {
            "_id" : check.currentMaxId + 5,
            "doc" : [ record ]
        });
    }
})

ध्यान दें कि aggregation , सर्वर साइड पर चलता है और बहुत कुशल है, यह भी ध्यान दें कि aggregation आपको एक दस्तावेज़ लौटाएगा कर्सर . के बजाय संस्करणों में previous to 2.6 . तो आपको उपरोक्त कोड को संशोधित करने की आवश्यकता होगी ताकि कर्सर को पुनरावृत्त करने के बजाय केवल एक दस्तावेज़ से चयन किया जा सके।

दस्तावेज़ों के बीच में एक नया दस्तावेज़ सम्मिलित करना

अब, यदि आप दस्तावेज़ों के बीच एक नया दस्तावेज़ सम्मिलित करना चाहते हैं 1 और 2 , हम जानते हैं कि दस्तावेज़ _id=0 . के साथ कंटेनर के अंदर आना चाहिए और second . में रखा जाना चाहिए doc . में स्थिति उस कंटेनर की सरणी।

इसलिए, हम $each . का उपयोग करते हैं और $position विशिष्ट पदों में डालने के लिए ऑपरेटरों।

var record = {"name" : "insertInMiddle"};

db.col.update(
{
    "_id" : 0
}, {
    $push : {
        "doc" : {
            $each : [record],
            $position : 1
        }
    }
}
);

ओवर फ्लो को संभालना

अब, हमें overflowingदस्तावेजों की देखभाल करने की आवश्यकता है प्रत्येक container . में , मान लें कि हम बीच में _id=0 . के साथ कंटेनर में एक नया दस्तावेज़ सम्मिलित करते हैं . अगर कंटेनर में पहले से ही 5 है दस्तावेज़, हमें move the last document to the next container . की आवश्यकता है और ऐसा तब तक करें जब तक कि सभी कंटेनर अपनी क्षमता के भीतर दस्तावेज़ धारण न कर लें, यदि आवश्यक हो तो अंत में हमें अतिप्रवाह वाले दस्तावेज़ों को रखने के लिए एक कंटेनर बनाने की आवश्यकता है।

यह जटिल ऑपरेशन चाहिए सर्वर साइड . पर किया जाए . इसे संभालने के लिए, हम एक स्क्रिप्ट बना सकते हैं जैसे नीचे दी गई और register यह मोंगोडब के साथ।

db.system.js.save( {
    "_id" : "handleOverFlow",
    "value" : function handleOverFlow(id) {
        var currDocArr = db.col.find( {
            "_id" : id
        })[0].doc;
        print(currDocArr);
        var count = currDocArr.length;
        var nextColId = id + 5;
        // check if the collection size has exceeded
    if (count <= 5)
        return;
    else {
        // need to take the last doc and push it to the next capped 
    // container's array
    print("updating collection: " + id);
    var record = currDocArr.splice(currDocArr.length - 1, 1);
    // update the next collection
    db.col.update( {
        "_id" : nextColId
    }, {
        $push : {
            "doc" : {
                $each : record,
                $position : 0
            }
        }
    });
    // remove from original collection
    db.col.update( {
        "_id" : id
    }, {
        "doc" : currDocArr
    });
    // check overflow for the subsequent containers, recursively.
    handleOverFlow(nextColId);
}
}

ताकि after every insertion in between , हम इस function . को लागू कर सकते हैं कंटेनर आईडी पास करके, handleOverFlow(containerId)

सभी रिकॉर्ड को क्रम में लाया जा रहा है

बस $unwind का उपयोग करें aggregate pipeline में ऑपरेटर ।

db.col.aggregate([{$unwind:"$doc"},{$project:{"_id":0,"doc":1}}]);

दस्तावेजों का पुन:आदेश देना

आप प्रत्येक दस्तावेज़ को एक कैप्ड कंटेनर में "_id" फ़ील्ड के साथ संग्रहीत कर सकते हैं:

.."doc":[{"_id":0,","name":"xyz",...}..]..

कैप्ड कंटेनर के "doc" एरे को पकड़ें, जिसके आइटम्स को आप फिर से ऑर्डर करना चाहते हैं।

var docArray = db.col.find({"_id":0})[0];

उनकी आईडी अपडेट करें ताकि सॉर्ट करने के बाद आइटम का क्रम बदल जाए।

सरणी को उनके _ids के आधार पर क्रमबद्ध करें।

docArray.sort( function(a, b) {
    return a._id - b._id;
});

नए दस्तावेज़ सरणी के साथ कैप्ड कंटेनर को वापस अपडेट करें।

लेकिन फिर, सब कुछ उबलता है कि कौन सा दृष्टिकोण संभव है और आपकी आवश्यकता के अनुरूप सर्वोत्तम है।

आपके प्रश्नों पर आ रहा है:

Arrays के रूप में दस्तावेज़।

$each का उपयोग करें और $position db.collection.update() में ऑपरेटर्स मेरे उत्तर में दर्शाए अनुसार कार्य करें।

हाँ। यह प्रदर्शन को प्रभावित करेगा, जब तक कि संग्रह में बहुत कम डेटा न हो।

हाँ। कैप्ड संग्रह के साथ, आप डेटा खो सकते हैं।



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. जब मैं विंडोज सर्वर 2008 में 64-बिट मोंगोडब स्थापित करने का प्रयास करता हूं तो पहुंच को अस्वीकार कर दिया जाता है

  2. mongoDB संबंधित समस्या को कुशलतापूर्वक कैसे हल करें?

  3. वस्तु मूल्य विभाग के माध्यम से कैसे खोजें।नाम

  4. मोंगोडब में कुल अनुरोध के साथ तिथि के अनुसार क्रमबद्ध करें

  5. उल्का डेटा के लिए एक क्रमांकित सूची बनाना