3

I have a mongo document like below;

{
    "_id" : "123",
    "info" : {
        "batch" : "Batch1-Minor"
    },
    "batchElements" : {
        "elements" : [ 
             {
               "_id" : "elementId1",
               "type": "ABC"
             },  
             {
                "_id" : "elementId2",
                "type": "ABC"
             }
        ]
    }
}

How can generate an aggregated output by changing the _id field inside elements by concatenating $info.batch and $batchElements.elements._id

Expected Output:

{
    "_id" : "123",
    "info" : {
        "batch" : "Batch1-Minor"
    },
    "batchElements" : {
        "elements" : [ 
             {
               "_id" : "Batch1-Minor-elementId1",
               "type": "ABC"
             },  
             {
                "_id" : "Batch1-Minor-elementId2",
                "type": "ABC"
             }
        ]
    }
}
2
  • 1
    Aggregation queries can't write back to same collection, their main purpose if for querying not updating back, though there are two stages $out -- will overwrite the collection if existing or create a new & $merge - will write to new collection or create new (These two are not what we're looking at), So it has to be a normal update process, What is mongoDB version ? Commented Jan 16, 2020 at 16:57
  • 1
    Sorry for the confusion, I don't want to update the existing collection. How can i write an aggregation stage (mostly addFields) to generate the output. I will edit the original question with this. Commented Jan 16, 2020 at 17:09

1 Answer 1

3

With below query we're iterating through batchElements.elements & forming objects with type & _id & finally $map would push an array of objects back to batchElements.elements where $addFields would add the field to actual document, Try this :

db.yourCollectionName.aggregate([{
    $addFields: {
        'batchElements.elements': {
            $map:
            {
                input: "$batchElements.elements",
                as: "each",
                in: { type: '$$each.type', '_id': { $concat: ["$info.batch", "-", "$$each._id"] } }
               /** So if you've multiple fields in each object then instead of listing all, You need to use 
                in: { $mergeObjects: ["$$each", { '_id': { $concat: ["$info.batch", "-", "$$each._id"] } }] } */
            }
        }
    }
}])
Sign up to request clarification or add additional context in comments.

2 Comments

There can be many fields inside 'batchElements.elements' other than _id and type. Is there a way to avoid mentioning all of them inside 'in' clause?
@Boat : Yeah I suspected that, you can try updated query :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.