Ktulh
Ktulh

Reputation: 25

MongoDB aggregation get value from path containing variable

I have a collection datas like this:

[
  {
    "_id": 0,
    "languages": { "en": true },
    "translated_data": { "en": { "title": "eng title 1" } }
  },
  {
    "_id": 1,
    "languages": { "en": true },
    "translated_data": { "en": { "title": "eng title 2" } }
  }
]

And I need to transform it to a format like this:

[
  {
    "_id": 0,
    "translations": [{ "language": "en", "data": { "title": "eng title 1" } }]
  },
  {
    "_id": 1,
    "translations": [{ "language": "en", "data": { "title": "eng title 2" } }]
  }
]

I tried this update query but stuck

db.datas.updateMany({}, [
  {
    $set: {
      translations: {
        $map: {
          input: {
            $filter: {
              input: {
                $objectToArray: "$languages",
              },
              as: "language",
              cond: { $eq: ["$$language.v", true] },
            },
          },
          as: "language",
          in: {
            language: "$$language.k",
            data: "???", // get value from $translated_data[$$language.k]
          },
        },
      },
    },
  },
  {
    $unset: ["languages", "translated_data"],
  },
]);

Upvotes: 0

Views: 237

Answers (1)

Dheemanth Bhat
Dheemanth Bhat

Reputation: 4452

Try this:

db.datas.updateMany({},
    [
        {
            $set: {
                "translate_ok": {
                    $first: {
                        $map: {
                            input: { $objectToArray: "$languages" },
                            as: "language",
                            in: { $eq: ["$$language.v", true] },
                        }
                    }
                }
            }
        },
        {
            $set: {
                translations: {
                    $map: {
                        input: { $objectToArray: "$translated_data" },
                        as: "language",
                        in: {
                            $cond: [
                                "$translate_ok",
                                {
                                    language: "$$language.k",
                                    data: "$$language.v"
                                },
                                { 
                                    $arrayToObject: [["$$language"]]
                                }
                            ]
                        }
                    }
                }
            }
        },
        {
            $unset: ["languages", "translated_data", "translate_ok"]
        }
    ]
);

Output:

/* 1 */
{
    "_id" : 1,
    "translations" : [
        {
            "language" : "en",
            "data" : {
                "title" : "eng title 1"
            }
        }
    ]
},

/* 2 */
{
    "_id" : 2,
    "translations" : [
        {
            "en" : {
                "title" : "eng title 2"
            }
        }
    ]
}

My test data:

/* 1 */
{
    "_id" : 1,
    "languages" : {
        "en" : true
    },
    "translated_data" : {
        "en" : {
            "title" : "eng title 1"
        }
    }
},

/* 2 */
{
    "_id" : 2,
    "languages" : {
        "en" : false
    },
    "translated_data" : {
        "en" : {
            "title" : "eng title 2"
        }
    }
}

Upvotes: 1

Related Questions