Home > Back-end >  mongodb aggregations code for different language data in Nestjs
mongodb aggregations code for different language data in Nestjs

Time:02-25

my database

{
    "_id": {
        "$oid": "ddfsfs"
    },
    "id": 3,
    "parent_id": 6,
    "translation":
       [
        {
        "language": "en",
        "desc": "prod detail",
        "name": "example1"
        },
        {
        "language": "tr",
        "desc": "detaylar",
        "name": "ornek1"
        }
       ]
}

I want to make this : For example, only the English field is selected. Is it okay if it has only the name and description in the English field in its final form? and How?

{
    "_id": {
        "$oid": "ddfsfs"
    },
     "id": 3,
     "parent_id": 6,
     "desc": "prod detail",
     "name": "example1"   
}

or the database can be like this. again only the english field will remain

{
    "_id": {
        "$oid": "62189ffd81f6b6bb05d8d409"
    },
    "id": 7,
    "parent_id": 8,
    "en": {
        "desc": "hii",
        "name": "serial ethernet"
    },
    "tr": {
        "desc": "merhaba",
        "name": "seri ethernet"
    }
}

please share me mongodb aggregations code for use in nestjs. thank you!:)

CodePudding user response:

For the first database schema, you need a pipeline that will first filter the translation array using the $filter operator. This will return an array with just the document that satisfies the filtering condition. So the expression:

{ $filter: {
    input: '$translation',
    cond: { '$eq': ['$$this.language', 'en'] }
} }

yields the result

[
    {
        "language" : "en",
        "desc" : "prod detail",
        "name" : "example1
    }
]

The second step will be to merge the above document with the top-level fields you need, in this case you want the _id, id and parent_id fields to combine with the above. Use $mergeObjects for this.

Since $mergeObjects requires documents as input, you need to use $arrayElemAt or $first operator to get the document from the array in the previous $filter expression, i.e.

{ $arrayElemAt: [ 
    { $filter: {
        input: '$translation',
        cond: { '$eq': ['$$this.language', 'en'] }
    } }, 
    0 
] } 

or $first

{ $first: {
    $filter: {
        input: '$translation',
        cond: { '$eq': ['$$this.language', 'en'] }
    } 
} } 

will return

{
    "language" : "en",
    "desc" : "prod detail",
    "name" : "example1
}

Now you can use the expression

{
    $mergeObjects: [ 
        { _id: "$_id", id: '$id', parent_id: "$parent_id" },  
        { $arrayElemAt: [ 
            { $filter: {
                input: '$translation',
                cond: { '$eq': ['$$this.language', 'en'] }
            } }, 
            0 
        ] } 
    ] 
}

to get

{
    "_id" : ObjectId("6218abb521d9a0dfecd02e4b"),
    "parent_id" : 6.0,
    "language" : "en",
    "desc" : "prod detail",
    "name" : "example1"
}

Final step will be to replace the root with the operator $replaceRoot and your final aggregate pipeline Try the following aggregate pipeline (MongoDb Playground) should look like this

{ $replaceRoot: { 
    newRoot: { 
        $mergeObjects: [ 
            { _id: "$_id", id: '$id', parent_id: "$parent_id" },  
            { $arrayElemAt: [ 
                { $filter: {
                   input: '$translation',
                   cond: { '$eq': ['$$this.language', 'en'] }
                } }, 
                0 
            ] } 
        ] 
    } 
} } 

For the alternative schema run this aggregation pipeline where it's only a matter of merging the document with the en key i.e.

{ $replaceRoot: { 
    newRoot: { 
        $mergeObjects: [ 
            { _id: "$_id", id: '$id', parent_id: "$parent_id" },  
            '$en'
        ] 
    } 
} } 
  • Related