Untuk membuat kueri umum, seseorang memerlukan kerangka kerja agregasi karena memiliki beberapa operator praktis untuk membantu Anda dalam hal ini. Untuk memulainya, Anda perlu mengonversi dokumen yang disematkan menjadi larik pasangan kunci/nilai, lalu memfilter larik pada bidang kunci yang meneruskan lokal sebagai parameter.
Misalnya, mengonversi dokumen
"title": {
"en": "title en2",
"de": "title de2"
},
ke array
"title": [
{ "k": "en", '"v": "title en2" },
{ "k": "de", "v": "title de2" }
],
menggunakan $objectToArray
operator. Anda kemudian dapat memfilter larik ini pada bidang kunci menggunakan $filter
operator sebagai
{
'$filter': {
'input': { '$objectToArray': '$title' },
'cond': { '$eq': ['$$this.k', locale] }
}
}
di mana variabel lokal berasal dari parameter yang diteruskan.
Setelah Anda memiliki larik yang difilter, mendapatkan bidang nilai memerlukan $arrayElemAt
operator diterapkan pada kunci nilai sebagai
{
'$arrayElemAt': ['$title.v', 0]
}
Jadi pada akhirnya Anda harus menjalankan pipeline seperti ini:
var locale = 'en';
db.cs.aggregate([
{ '$match': { "cID" : "00001" } },
{ '$addFields': {
'title': {
'$filter': {
'input': { '$objectToArray': '$title' },
'cond': { '$eq': ['$$this.k', locale] }
}
},
'desc': {
'$filter': {
'input': { '$objectToArray': '$desc' },
'cond': { '$eq': ['$$this.k', locale] }
}
}
} },
{ '$addFields': {
'title': {
'$arrayElemAt': ['$title.v', 0]
},
'desc': {
'$arrayElemAt': ['$desc.v', 0]
}
} }
]);
Dan dengan beberapa pemfaktoran ulang:
var locale = 'en';
var getFilterOperatorExpression = function (field) {
return {
'$filter': {
'input': { '$objectToArray': '$'+ field },
'cond': { '$eq': ['$$this.k', locale] }
}
}
};
var getValueOperatorExpression = function (field) {
return {
'$arrayElemAt': ['$'+ field +'.v', 0]
}
};
db.cs.aggregate([
{ '$match': { "cID" : "00001" } },
{ '$addFields': {
'title': getFilterOperatorExpression('title'),
'desc': getFilterOperatorExpression('desc'),
} },
{ '$addFields': {
'title': getValueOperatorExpression('title'),
'desc': getValueOperatorExpression('desc')
} }
]);