3

I have a question about how to create output from 2 arrays one array with translation key and another with translation i would output as

"translation_key":"value"  

Current output:
{

        "_id" : ObjectId("5bfc0b2b30c4683f585078fb"),
        "translation" : [ 
            "hour", 
            "day"

        ],
        "translation_key" : [ 
            "HOUR_TEXT", 
            "DAY_TEXT"  


        ],
        "locale_id" : "EN_en"
   }

OUTPUT should be :

{
    "EN_en" :{
        "HOUR_TEXT" :"hour",
        "DAY_TEXT" :"day",
    }
}
Ashh
  • 44,693
  • 14
  • 105
  • 132
Maco
  • 113
  • 6
  • 12

2 Answers2

3

You can use below aggregation

You can use $range to get index from both the arrays and can create key (k) and value (v) pair for the resultant array and then finally $arrayToObject to convert resultant array into single document.

db.collection.aggregate([
  { "$replaceRoot": {
    "newRoot": {
      "$arrayToObject": [[
        {
          "k": "$locale_id",
          "v": {
            "$arrayToObject": {
              "$map": {
                "input": { "$range": [0, { "$size": "$translation_key" }] },
                "in": {
                  "k": { "$arrayElemAt": ["$translation_key", "$$this"] },
                  "v": { "$arrayElemAt": ["$translation", "$$this"] }
                }
              }
            }
          }
        }
      ]]
    }
  }}
])

Which returns

[
  {
    "EN_en": {
      "DAY_TEXT": "day",
      "HOUR_TEXT": "hour"
    }
  }
]
Ashh
  • 44,693
  • 14
  • 105
  • 132
2

You can try below aggregation:

db.col.aggregate([
    {
        $project: {
            array: [
                {
                    k: "$locale_id",
                    v: {
                        $arrayToObject: {
                            $map: {
                                input: { $range: [0, { $size: "$translation" }] },
                                as: "index",
                                in: {
                                    k: { $arrayElemAt: [ "$translation", "$$index" ] },
                                    v: { $arrayElemAt: [ "$translation_key", "$$index" ] }
                                }
                            }
                        }
                    }
                }
            ]
        }
    },
    {
        $replaceRoot: {
            newRoot: { $arrayToObject: "$array" }
        }
    }
])

Basically you need to use $arrayToObject operator to manipulate your key names and in your case it should be used twice. This operator expects an array of objects with two properties k and v and therefore you should use $map to generate that values based on translation, $range is used to generate indexes to traverse translation and translation_key arrays. Then you can use $replaceRoot to promote dynamically generated key into root level of your document.

Output:

{ "EN_en" : { "hour" : "HOUR_TEXT", "day" : "DAY_TEXT" } }
mickl
  • 48,568
  • 9
  • 60
  • 89
  • and how could i do this ... from ... { "EN_en" : { "hour" : "HOUR_TEXT", "day" : "DAY_TEXT" } } { "ES_en" : { "hour" : "HOUR_TEXT", "day" : "DAY_TEXT" } } to ... {"EN_en" : { "key":value}},"ES_es":{"key":value"}} } – Maco Nov 27 '18 at 07:24
  • 1
    You need to push multiple documents into `array` – mickl Nov 27 '18 at 07:25
  • { "0" : { "test12" : { "in about a year" : "" } }, "1" : { "q23221312" : { "in about a year" : "" } }, "2" : { "ES_es" : { "in about a year" : "" } }, "3" : { "EN_en" : { "in about a year" : "in about a year" } } } how to do that ? what i wrote 1 comment before ? :o – Maco Nov 27 '18 at 10:10
  • 1
    @Maco please open a separate question just to avoid confusion and let this question be simple and clear for future users, I will try to take a look at this new question – mickl Nov 27 '18 at 16:04