नई प्रतिक्रिया
डेटा प्रिंट करें
db.test.find().forEach(doc => {
doc.details = doc.details.map( detail => {
Object.keys(detail).filter( k => k !== "_id" ).forEach( k => {
detail[k].forEach( item => {
Object.keys(item).filter(i => i !== "_id" ).forEach( inner => {
detail[k + inner.charAt(0).toUpperCase() + inner.substr(1)]
= item[inner];
})
});
delete detail[k];
});
return detail;
});
printjson(doc);
});
डेटा अपडेट करें
db.test.find().forEach(doc => {
doc.details = doc.details.map( detail => {
Object.keys(detail).filter( k => k !== "_id" ).forEach( k => {
detail[k].forEach( item => {
Object.keys(item).filter(i => i !== "_id" ).forEach( inner => {
detail[k + inner.charAt(0).toUpperCase() + inner.substr(1)]
= item[inner];
})
});
delete detail[k];
});
return detail;
});
ops = [
...ops,
{ "updateOne": {
"filter": { "_id": doc._id },
"update": { "$set": { "doc.details": doc.details } }
}}
];
if ( ops.length >= 500 ) {
db.test.bulkWrite(ops);
ops = [];
}
});
if ( ops.length > 0 ) {
db.test.bulkWrite(ops);
ops = [];
}
आउटपुट फॉर्म
{
"_id" : ObjectId("58e574a768afb6085ec3a388"),
"details" : [
{
"_id" : ObjectId("58e55f0f68afb6085ec3a2cc"),
"aUnit" : "08",
"aSize" : "5",
"aPos" : "Far",
"bUnit" : "08",
"bSize" : "5",
"bPos" : "Far",
"cUnit" : "08",
"cSize" : "3",
"cPos" : "Far",
"dUnit" : "08",
"dSize" : "5",
"dPos" : "Far"
}
]
}
मूल डेटा
{
"_id" : ObjectId("58e574a768afb6085ec3a388"),
"tests" : [
{
"_id" : ObjectId("58e542fb68afb6085ec3a1d2"),
"details" : [
{
"a" : [
{
"unit" : "08",
"size" : "5",
"pos" : "Far",
"_id" : ObjectId("58e542fb68afb6085ec3a1d6")
}
]
},
{
"b" : [
{
"pos" : "Drive Side Far",
"size" : "5",
"unit" : "08",
"_id" : ObjectId("58e542fb68afb6085ec3a1d3")
}
]
},
{
"c" : [
{
"pos" : "Far",
"size" : "3",
"unit" : "08",
"_id" : ObjectId("58e542fb68afb6085ec3a1d4")
}
]
},
{
"d" : [
{
"pos" : "Far",
"size" : "5",
"unit" : "08",
"_id" : ObjectId("58e542fb68afb6085ec3a1d5")
}
]
}
]
}
]
}
मूल उत्तर
यदि आप अपने डेटा को "अपडेट" करने का प्रयास कर रहे हैं, तो आप जो प्रयास कर रहे हैं उससे कहीं अधिक इसमें शामिल है। आपके पास कई सरणियाँ हैं और आपको सीधे उन तक पहुँचने की कोशिश करने के बजाय सरणी तत्वों को वास्तव में "ट्रैवर्स" करने की आवश्यकता है।
"चपटा" डेटा को "प्रिंट आउट" करने के लिए यहां एक नमूना दिया गया है:
db.test.find().forEach(doc => {
doc.tests = doc.tests.map( test => {
test.details.forEach( detail => {
Object.keys(detail).forEach( key => {
detail[key].forEach( item => {
Object.keys(item).forEach( inner => {
if ( inner !== '_id' ) {
test[key + inner.charAt(0).toUpperCase() + inner.substr(1)]
= item[inner];
}
});
});
});
});
delete test.details;
return test;
});
printjson(doc);
})
जो मुझे लगता है कि वह संरचना देता है जिसे आप ढूंढ रहे हैं:
{
"_id" : ObjectId("58e574a768afb6085ec3a388"),
"tests" : [
{
"_id" : ObjectId("58e542fb68afb6085ec3a1d2"),
"aUnit" : "08",
"aSize" : "5",
"aPos" : "Far",
"bPos" : "Drive Side Far",
"bSize" : "5",
"bUnit" : "08",
"cPos" : "Far",
"cSize" : "3",
"cUnit" : "08",
"dPos" : "Far",
"dSize" : "5",
"dUnit" : "08"
}
]
}
अब मैं आपके "details"
. के अंदर किसी भी संभावना को ध्यान में नहीं रख रहा हूं दस्तावेज़ों को "a"
. जैसी कुंजियों से व्यवस्थित करें आदि शायद कई बार प्रकट हो सकता है। तो मैं सिर्फ इस बात पर विचार कर रहा हूं कि वहां केवल 1 दस्तावेज़ है जिसमें एक "a"
. है या एक "b"
आदि, और "details"
के शीर्ष स्तर पर नई कुंजी जोड़ते समय उस कुंजी से मेल खाने वाला अंतिम पाया गया मान हमेशा असाइन किया जाता है दस्तावेज़।
यदि आप वास्तविक मामले में भिन्न हैं, तो आपको विभिन्न .forEach()
. को संशोधित करने की आवश्यकता होगी एक पैरामीटर के रूप में "इंडेक्स" का उपयोग करने के लिए वहां लूप करता है और उस इंडेक्स वैल्यू को कुंजी नाम के हिस्से के रूप में शामिल करता है। यानी:
"a0Unit": "08",
"a0Size": "05",
"a1Unit": "09",
"a1Size": "06"
लेकिन यह एक विवरण है यदि आवश्यक हो तो आपको काम करना होगा क्योंकि यह प्रश्न में डेटा प्रस्तुत करने के तरीके से भिन्न होगा।
यदि फिर भी आप जिसे अपडेट करना चाहते हैं, उसके लिए यह एकदम उपयुक्त है, तो बस .bulkWrite()
नियमित अंतराल पर क्रियान्वित बयान:
let ops = [];
db.test.find().forEach(doc => {
doc.tests = doc.tests.map( test => {
test.details.forEach( detail => {
Object.keys(detail).forEach( key => {
detail[key].forEach( item => {
Object.keys(item).forEach( inner => {
if ( inner !== '_id' ) {
test[key + inner.charAt(0).toUpperCase() + inner.substr(1)]
= item[inner];
}
});
});
});
});
delete test.details;
return test;
});
ops = [
...ops,
{ "updateOne": {
"filter": { "_id": doc._id },
"update": { "$set": { "tests": doc.tests } }
}}
];
if ( ops.length >= 500 ) {
db.test.bulkWrite(ops);
ops = [];
}
});
if ( ops.length > 0 ) {
db.test.bulkWrite(ops);
ops = [];
}
यह _id
. से भी दिखाई देता है प्रत्येक सरणी सदस्य दस्तावेज़ में मौजूद फ़ील्ड जिसे आप नेवला का उपयोग कर रहे हैं। तो आप जो भी करें, नेवले का उपयोग करके कोड को चलाने की कोशिश न करें। यह आपके डेटा का "वन ऑफ" बल्क अपडेट है और इसे सीधे शेल से चलाया जाना चाहिए। फिर निश्चित रूप से आपको नई संरचना के अनुरूप अपनी स्कीमा को संशोधित करने की आवश्यकता होगी।
लेकिन यही कारण है कि आपको शेल में अपने डेटा को printjson()
. के साथ चलाना चाहिए विधि पहले।