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

सरणी mongodb के अंदर नेस्टेड सरणी अद्यतन कर रहा है

MongoDB 3.6 और नया

MongoDB 3.6 और इसके बाद के संस्करण के साथ एक नई सुविधा आती है जो आपको स्थितीय फ़िल्टर किए गए $\[\] का उपयोग करके नेस्टेड सरणियों को अपडेट करने की अनुमति देती है। विशिष्ट तत्वों से मेल खाने के लिए वाक्यविन्यास और arrayFilters . के माध्यम से विभिन्न शर्तों को लागू करने के लिए अपडेट स्टेटमेंट में:

const { oid, pid } = req.params;
const { name, oName, description, type } = req.body; 

collection.update(
    {
        "_id": 1,
        "operations": {
            "$elemMatch": {
                oid, "parameters.pid": pid
            }
        }
    },
    { "$set": { 
        "operations.$[outer].parameters.$[inner].name": name,
        "operations.$[outer].parameters.$[inner].description": description,
        "operations.$[outer].parameters.$[inner].oName": oName,
        "operations.$[outer].parameters.$[inner].type": type 
    } },
    { "arrayFilters": [
        { "outer.oid": oid },
        { "inner.pid": pid }
    ] }, (err, result) => {
    if (err) {
        console.log('Error updating service: ' + err);
        res.send({'error':'An error has occurred'});
    } else {
        // console.log('' + result + ' document(s) updated');
        res.send(result);
    }
});

MongoDB 3.4 और पुराने के लिए:

जैसा कि @wdberkeley ने अपनी टिप्पणी में उल्लेख किया है:

<ब्लॉकक्वॉट>

MongoDB एक सरणी के एक से अधिक स्तरों में मिलान का समर्थन नहीं करता है। अपने दस्तावेज़ मॉडल को बदलने पर विचार करें ताकि प्रत्येक दस्तावेज़ एक ऑपरेशन का प्रतिनिधित्व करे, जिसमें ऑपरेशन दस्तावेज़ों में डुप्लिकेट ऑपरेशन के सेट के लिए सामान्य जानकारी हो।

मैं उपरोक्त के साथ सहमत हूं और आपकी स्कीमा को फिर से डिजाइन करने की अनुशंसा करता हूं क्योंकि मोंगोडीबी इंजन एकाधिक स्थितीय ऑपरेटरों का समर्थन नहीं करता है (देखें नेस्टेड सरणियों को अपडेट करने के लिए ऑपरेटर )

हालांकि, यदि आप पहले से अद्यतन किए जाने वाले पैरामीटर ऑब्जेक्ट वाले संचालन सरणी की अनुक्रमणिका जानते हैं तो अद्यतन क्वेरी होगी:

db.collection.update(
    {
        "_id" : "04", 
        "operations.parameters.pid": "011"
    }, 
    {
        "$set": { 
            "operations.0.parameters.$.name": "foo",
            "operations.0.parameters.$.description": "bar", 
            "operations.0.parameters.$.type": "foo" 
        }
    }
)

संपादित करें:

अगर आप $set बनाना चाहते हैं फ्लाई पर स्थितियां यानी कुछ ऐसा जो आपको वस्तुओं के लिए इंडेक्स प्राप्त करने में मदद करेगा और फिर तदनुसार संशोधित करेगा, फिर MapReduce का उपयोग करने पर विचार करें। ।

वर्तमान में यह एकत्रीकरण ढांचे का उपयोग करना संभव नहीं लगता है। एक अनसुलझा खुला है JIRA मुद्दा उससे जुड़ा हुआ है। हालांकि, MapReduce . के साथ समाधान संभव है . MapReduce के साथ मूल विचार यह है कि यह जावास्क्रिप्ट को अपनी क्वेरी भाषा के रूप में उपयोग करता है लेकिन यह एकत्रीकरण ढांचे की तुलना में काफी धीमा है और वास्तविक समय डेटा विश्लेषण के लिए इसका उपयोग नहीं किया जाना चाहिए।

अपने MapReduce ऑपरेशन में, आपको कुछ चरणों को परिभाषित करने की आवश्यकता है यानी मैपिंग चरण (जो संग्रह में प्रत्येक दस्तावेज़ में एक ऑपरेशन को मैप करता है, और ऑपरेशन या तो कुछ भी नहीं कर सकता है या कुछ ऑब्जेक्ट को चाबियों और अनुमानित मूल्यों के साथ उत्सर्जित कर सकता है) और चरण को कम करना ( जो उत्सर्जित मूल्यों की सूची लेता है और इसे एक तत्व में कम कर देता है)।

मानचित्र चरण के लिए, आप आदर्श रूप से संग्रह में प्रत्येक दस्तावेज़ के लिए, प्रत्येक संचालन के लिए अनुक्रमणिका प्राप्त करना चाहेंगे सरणी फ़ील्ड और दूसरी कुंजी जिसमें $set . है कुंजियाँ।

आपका कम कदम एक फ़ंक्शन होगा (जो कुछ भी नहीं करता है) जिसे केवल var reduce =function() {}; के रूप में परिभाषित किया गया है

आपके MapReduce ऑपरेशन का अंतिम चरण तब एक अलग संग्रह संचालन बनाएगा जिसमें $set फ़ील्ड के साथ-साथ उत्सर्जित संचालन सरणी ऑब्जेक्ट शामिल होगा। स्थितियाँ। जब आप मूल संग्रह पर MapReduce ऑपरेशन चलाते हैं तो इस संग्रह को समय-समय पर अपडेट किया जा सकता है। कुल मिलाकर, यह MapReduce विधि इस तरह दिखेगी:

var map = function(){
    for(var i = 0; i < this.operations.length; i++){
        emit( 
            {
                "_id": this._id, 
                "index": i 
            }, 
            {
                "index": i, 
                "operations": this.operations[i],            
                "update": {
                    "name": "operations." + i.toString() + ".parameters.$.name",
                    "description": "operations." + i.toString() + ".parameters.$.description",
                    "type": "operations." + i.toString() + ".parameters.$.type"
                }                    
            }
        );
    }
};

var reduce = function(){};

db.collection.mapReduce(
    map,
    reduce,
    {
        "out": {
            "replace": "operations"
        }
    }
);

आउटपुट संग्रह को क्वेरी करना संचालन MapReduce ऑपरेशन से आम तौर पर आपको परिणाम मिलेगा:

db.operations.findOne()

आउटपुट :

{
    "_id" : {
        "_id" : "03",
        "index" : 0
    },
    "value" : {
        "index" : 0,
        "operations" : {
            "_id" : "96",
            "oName" : "test op 52222222222",
            "sid" : "04",
            "name" : "test op 52222222222",
            "oid" : "99",
            "description" : "testing",
            "returntype" : "test",
            "parameters" : [ 
                {
                    "oName" : "Param1",
                    "name" : "foo",
                    "pid" : "011",
                    "type" : "foo",
                    "description" : "bar",
                    "value" : ""
                }, 
                {
                    "oName" : "Param2",
                    "name" : "Param2",
                    "pid" : "012",
                    "type" : "58222",
                    "description" : "testing",
                    "value" : ""
                }
            ]
        },
        "update" : {
            "name" : "operations.0.parameters.$.name",
            "description" : "operations.0.parameters.$.description",
            "type" : "operations.0.parameters.$.type"
        }
    }
}

फिर आप db.operations.find() . से कर्सर का उपयोग कर सकते हैं अपने संग्रह को फिर से चालू करने और तदनुसार अपने संग्रह को अपडेट करने का तरीका:

var oid = req.params.operations;
var pid = req.params.parameters;
var cur = db.operations.find({"_id._id": oid, "value.operations.parameters.pid": pid });

// Iterate through results and update using the update query object set dynamically by using the array-index syntax.
while (cur.hasNext()) {
    var doc = cur.next();
    var update = { "$set": {} };
    // set the update query object
    update["$set"][doc.value.update.name] = req.body.name;
    update["$set"][doc.value.update.description] = req.body.description;
    update["$set"][doc.value.update.type] = req.body.type;

    db.collection.update(
        {
            "_id" : oid, 
            "operations.parameters.pid": pid
        }, 
        update 
    );
};


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Django में GraphQL का उपयोग करके MongoDB से डेटा क्वेरी करना:गेट-गो (1)

  2. एक सरणी को फ़िल्टर करने और संबंधित सामग्री को पॉप्युलेट करने के लिए नेवला क्वेरी

  3. सी # 2.1 ड्राइवर से मोंगोडीबी डेटाबेस कनेक्शन को ठीक से बंद करना?

  4. प्रत्येक के लिए मोंगोडीबी ()

  5. mongodb में arrayFilters