Respons Baru
Cetak data
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);
});
Perbarui data
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 = [];
}
Formulir Keluaran
{
"_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"
}
]
}
Data Asli
{
"_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")
}
]
}
]
}
]
}
Jawaban Asli
Jika Anda mencoba "memperbarui" data Anda, maka itu jauh lebih terlibat daripada apa yang Anda coba. Anda memiliki beberapa larik dan Anda harus benar-benar "melintasi" elemen larik daripada mencoba mengaksesnya secara langsung.
Ini hanya contoh untuk "mencetak" data yang "diratakan":
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);
})
Yang saya yakini memberikan struktur yang Anda cari:
{
"_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"
}
]
}
Sekarang saya tidak memperhitungkan kemungkinan apa pun yang ada di dalam "details"
. Anda susun dokumen dengan kunci seperti "a"
dll mungkin bisa muncul beberapa kali. Jadi saya hanya mempertimbangkan bahwa hanya ada 1 dokumen di dalamnya yang memiliki "a"
atau "b"
dll, dan nilai terakhir yang cocok dengan kunci itu selalu ditetapkan saat menambahkan kunci baru ke tingkat atas "details"
dokumen.
Jika kasus aktual Anda bervariasi, maka Anda perlu memodifikasi berbagai .forEach()
loop di dalam sana juga menggunakan "indeks" sebagai parameter dan memasukkan nilai indeks itu sebagai bagian dari nama kunci. yaitu:
"a0Unit": "08",
"a0Size": "05",
"a1Unit": "09",
"a1Size": "06"
Tapi itu adalah detail yang harus Anda kerjakan jika perlu karena ini akan berbeda dari bagaimana data disajikan dalam pertanyaan.
Namun jika ini sangat cocok untuk apa yang ingin Anda perbarui, maka jalankan loop dengan .bulkWrite()
pernyataan yang dieksekusi secara berkala:
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 = [];
}
Itu juga muncul dari _id
bidang yang ada di setiap dokumen anggota array yang Anda gunakan luwak. Jadi apa pun yang Anda lakukan, jangan mencoba dan menjalankan kode menggunakan luwak itu sendiri. Ini adalah pembaruan massal "satu kali" dari data Anda dan harus dijalankan langsung dari shell. Maka tentu saja Anda perlu memodifikasi skema Anda agar sesuai dengan struktur baru.
Tapi inilah mengapa Anda harus menjalankan data Anda di shell dengan printjson()
metode terlebih dahulu.