MongoDB 3.6 और नए के लिए, $replaceRoot
पाइपलाइन जिसे $ के संयोजन में लागू किया जा सकता है मर्जऑब्जेक्ट्स
ऑपरेटर के रूप में newRoot
अभिव्यक्ति।
यह अभिव्यक्ति
{ "$mergeObjects": ["$subdoc", "$$ROOT"] }
दस्तावेज़ में शीर्ष स्तर के फ़ील्ड को सबडॉक एम्बेडेड फ़ील्ड्स के साथ मर्ज कर देगा ताकि अंत में आपका समग्र ऑपरेशन इस प्रकार होगा:
db.collection.aggregate([
{ "$replaceRoot": {
"newRoot": {
"$mergeObjects": [ "$subdoc", "$$ROOT" ]
}
} },
{ "$project": { "subdoc": 0 } }
])
अन्यथा आपको उन सभी डायनामिक कुंजियों को प्राप्त करने के लिए एक तंत्र की आवश्यकता होगी जिनकी आपको डायनामिक $project
को असेंबल करने की आवश्यकता है दस्तावेज़। यह Map-Reduce
के ज़रिए संभव है . निम्नलिखित मैप्रेड्यूस ऑपरेशन _id
. के रूप में सभी कुंजियों के साथ एक अलग संग्रह को पॉप्युलेट करेगा मान:
mr = db.runCommand({
"mapreduce": "my_collection",
"map" : function() {
for (var key in this.subdoc) { emit(key, null); }
},
"reduce" : function(key, stuff) { return null; },
"out": "my_collection" + "_keys"
})
सभी गतिशील कुंजियों की सूची प्राप्त करने के लिए, परिणामी संग्रह पर अलग-अलग चलाएं:
db[mr.result].distinct("_id")
["field2", "field3", ...]
अब ऊपर दी गई सूची को देखते हुए, आप अपने $project
. को असेंबल कर सकते हैं एक ऑब्जेक्ट बनाकर एकत्रीकरण पाइपलाइन दस्तावेज़ जिसमें इसके गुण लूप के भीतर सेट होंगे। आम तौर पर आपका $प्रोजेक्ट
दस्तावेज़ में यह संरचना होगी:
var project = {
"$project": {
"field1": 1,
"field2": "$subdoc.field2",
"field3": "$subdoc.field3"
}
};
इसलिए उप-दस्तावेज़ कुंजियों की उपरोक्त सूची का उपयोग करके, आप जावास्क्रिप्ट के reduce()
विधि:
var subdocKeys = db[mr.result].distinct("_id"),
obj = subdocKeys.reduce(function (o, v){
o[v] = "$subdoc." + v;
return o;
}, { "field1": 1 }),
project = { "$project": obj };
db.collection.aggregate([project]);