I need to access the data from the multi nested subdocument by omitting some fields of the nested document. The schema is shown below and the output expected is also shown below. Since projections cannot be used at the nested level so how can I do that?
given below is the database schema which is having nested entries as shown.
[
{
"_id": {
"$oid": "60e519db4e0f140328adc7c7"
},
"trans": {
"en": {
"name": "Graphics And Design",
"description": "Graphics And Design"
},
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"slug": "graphics-and-design",
"image": "",
"created_at": {
"$numberDouble": "1625627099104.0"
},
"subcategories": [
{
"trans": {
"en": {
"name": "LOGO DESIGN",
"description": "LOGO DESIGN"
},
"fr": {
"name": "LOGO DESIGN",
"description": "LOGO DESIGN"
}
},
"counts": {
"$numberInt": "0"
},
"slug": "logo-design",
"is_visible": true,
"image": "",
"_id": {
"$oid": "60e51a116678530e84ee2e61"
},
"created_at": {
"$numberDouble": "1625627153535.0"
},
"service_type": [
{
"trans": {
"en": {
"name": "3D logo",
"description": "3D logo design"
},
"fr": {
"name": "3D logo",
"description": "3D logo design"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"_id": {
"$oid": "60e51a116678530e84ee2e60"
},
"image": "",
"slug": "null",
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": []
}
]
},
{
"trans": {
"en": {
"name": "BRAND STYLE GUIDES",
"description": "BRAND STYLE GUIDES"
},
"fr": {
"name": "BRAND STYLE GUIDES",
"description": "BRAND STYLE GUIDES"
}
},
"counts": {
"$numberInt": "0"
},
"slug": "brand-style-guides",
"is_visible": true,
"image": "",
"_id": {
"$oid": "60e51a116678530e84ee2e63"
},
"created_at": {
"$numberDouble": "1625627153535.0"
},
"service_type": [
{
"trans": {
"en": {
"name": "Brand style 1",
"description": "Brand style 1"
},
"fr": {
"name": "Brand style 1",
"description": "Brand style 1"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"_id": {
"$oid": "60e51a116678530e84ee2e62"
},
"image": "",
"slug": "null",
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": []
},
{
"trans": {
"en": {
"name": "Brand style 2",
"description": "Brand style 2"
},
"fr": {
"name": "Brand style 2",
"description": "Brand style 2"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"_id": {
"$oid": "60e51a116678530e84ee2e62"
},
"image": "",
"slug": "null",
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": []
}
]
}
],
"updated_at": {
"$date": {
"$numberLong": "1625627153547"
}
}
},
//this is the another category
{
"_id": {
"$oid": "60e519db4e0f140328adc7c8"
},
"trans": {
"en": {
"name": "Graphics And Design2",
"description": "Graphics And Design2"
},
"fr": {
"name": "Graphics And Design2",
"description": "Graphics And Design2"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"slug": "graphics-and-design2",
"image": "",
"created_at": {
"$numberDouble": "1625627099104.0"
},
"subcategories": [
{
"trans": {
"en": {
"name": "LOGO DESIGN2",
"description": "LOGO DESIGN2"
},
"fr": {
"name": "LOGO DESIGN2",
"description": "LOGO DESIGN2"
}
},
"counts": {
"$numberInt": "0"
},
"slug": "logo-design2",
"is_visible": true,
"image": "",
"_id": {
"$oid": "60e51a116678530e84ee2e61"
},
"created_at": {
"$numberDouble": "1625627153535.0"
},
"service_type": [
{
"trans": {
"en": {
"name": "3D logo2",
"description": "3D logo design2"
},
"fr": {
"name": "3D logo2",
"description": "3D logo design2"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"_id": {
"$oid": "60e51a116678530e84ee2e60"
},
"image": "",
"slug": "null",
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": []
}
]
},
{
"trans": {
"en": {
"name": "BRAND STYLE GUIDES2",
"description": "BRAND STYLE GUIDES2"
},
"fr": {
"name": "BRAND STYLE GUIDES2",
"description": "BRAND STYLE GUIDES2"
}
},
"counts": {
"$numberInt": "0"
},
"slug": "brand-style-guides2",
"is_visible": true,
"image": "",
"_id": {
"$oid": "60e51a116678530e84ee2e63"
},
"created_at": {
"$numberDouble": "1625627153535.0"
},
"service_type": [
{
"trans": {
"en": {
"name": "Brand style 12",
"description": "Brand style 12"
},
"fr": {
"name": "Brand style 12",
"description": "Brand style 12"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"_id": {
"$oid": "60e51a116678530e84ee2e62"
},
"image": "",
"slug": "null",
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": []
},
{
"trans": {
"en": {
"name": "Brand style 22",
"description": "Brand style 22"
},
"fr": {
"name": "Brand style 22",
"description": "Brand style 22"
}
},
"counts": {
"$numberInt": "0"
},
"is_visible": true,
"_id": {
"$oid": "60e51a116678530e84ee2e62"
},
"image": "",
"slug": "null",
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": []
}
]
}
],
"updated_at": {
"$date": {
"$numberLong": "1625627153547"
}
}
}
]
Code I have tried so far:
const client = await Database.connect();
const lang = "en";
const r = await client
.collection("categories")
.aggregate([
{
$addFields: {
categories: {
$map: {
input: "$categories",
as: "c",
in: {
$mergeObjects: [
"$$this",
{
trans: `$$c.trans.${lang}`,
subcategories: {
$map: {
input: "$subcategories",
as: "s",
in: {
$mergeObjects: [
"$$this",
{
trans: `$$s.trans.${lang}`,
service_type: {
$map: {
input: "$$s.service_type",
as: "d",
in: {
$mergeObjects: [
"$$this",
{ trans: `$$d.trans.${lang}` },
],
},
},
},
},
],
},
},
},
},
],
},
},
},
},
},
])
.toArray();
console.log(r);
Response of console.log(r)
:
:: FieldPath field names may not start with '$'
Expected output:
[
{
"_id": ObjectId("60e519db4e0f140328adc7c7"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627099104.0"
},
"image": "",
"is_visible": true,
"slug": "graphics-and-design",
"subcategories": [
{
"_id": ObjectId("60e51a116678530e84ee2e61"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"image": "",
"is_visible": true,
"service_type": [
{
"_id": ObjectId("60e51a116678530e84ee2e60"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": [],
"image": "",
"is_visible": true,
"slug": "service_type1",
"trans": {
"description": "service_type1",
"name": "service_type1"
}
}
],
"slug": "logo-design",
"trans": {
"description": "LOGO DESIGN",
"name": "LOGO DESIGN"
}
},
{
"_id": ObjectId("60e51a116678530e84ee2e63"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"image": "",
"is_visible": true,
"service_type": [
{
"_id": ObjectId("60e51a116678530e84ee2e62"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": [],
"image": "",
"is_visible": true,
"slug": "null",
"trans": {
"description": "ServiceType1_BRAND STYLE GUIDES",
"name": "ServiceType1_BRAND STYLE GUIDES"
}
},
{
"_id": ObjectId("60e51a116678530e84ee2e62"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": [],
"image": "",
"is_visible": true,
"slug": "null",
"trans": {
"description": "ServiceType2_BRAND STYLE GUIDES",
"name": "ServiceType2_BRAND STYLE GUIDES"
}
}
],
"slug": "brand-style-guides",
"trans": {
"description": "BRAND STYLE GUIDES",
"name": "BRAND STYLE GUIDES"
}
}
],
"trans": {
"description": "Graphics And Design",
"name": "Graphics And Design"
},
"updated_at": ISODate("2021-07-07T03:05:53.547Z")
},
{
"_id": ObjectId("60e519db4e0f140328adc7c8"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627099104.0"
},
"image": "",
"is_visible": true,
"slug": "graphics-and-design2",
"subcategories": [
{
"_id": ObjectId("60e51a116678530e84ee2e61"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"image": "",
"is_visible": true,
"service_type": [
{
"_id": ObjectId("60e51a116678530e84ee2e60"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": [],
"image": "",
"is_visible": true,
"slug": "null",
"trans": {
"description": "ServiceType1_LOGO DESIGN2",
"name": "ServiceType1_LOGO DESIGN2"
}
}
],
"slug": "logo-design2",
"trans": {
"description": "LOGO DESIGN2",
"name": "LOGO DESIGN2"
}
},
{
"_id": ObjectId("60e51a116678530e84ee2e63"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"image": "",
"is_visible": true,
"service_type": [
{
"_id": ObjectId("60e51a116678530e84ee2e62"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": [],
"image": "",
"is_visible": true,
"slug": "null",
"trans": {
"description": "ServiceType1_BRAND STYLE GUIDES2",
"name": "ServiceType1_BRAND STYLE GUIDES2"
}
},
{
"_id": ObjectId("60e51a116678530e84ee2e62"),
"counts": 0,
"created_at": {
"$numberDouble": "1625627153535.0"
},
"gig_meta_data": [],
"image": "",
"is_visible": true,
"slug": "null",
"trans": {
"description": "ServiceType2_BRAND STYLE GUIDES2",
"name": "ServiceType2_BRAND STYLE GUIDES2"
}
}
],
"slug": "brand-style-guides2",
"trans": {
"description": "BRAND STYLE GUIDES2",
"name": "BRAND STYLE GUIDES2"
}
}
],
"trans": {
"description": "Graphics And Design2",
"name": "Graphics And Design2"
},
"updated_at": ISODate("2021-07-07T03:05:53.547Z")
}
]
please help in resolving this issue with any good and valid approaches.
I am not getting your try, you can try the below approach,
$map
to iterate loop of subcategories
array$map
to iterate loop of service_type
arraytrans
object by input language$mergeObjects
to merge updated trans
field and current object of service_type
array$mergeObjects
to merge updated trans
and service_type
array with current object of subcategories
arrayvar lang = "en";
const r = await client.collection("categories").aggregate([
{
$addFields: {
trans: "$trans.en",
subcategories: {
$map: {
input: "$subcategories",
as: "s",
in: {
$mergeObjects: [
"$$s",
{
trans: `$$s.trans.${lang}`,
service_type: {
$map: {
input: "$$s.service_type",
in: {
$mergeObjects: ["$$this", { trans: `$$this.trans.${lang}` }]
}
}
}
}
]
}
}
}
}
}
]).toArray();
console.log(r);