Convert ObjectId to String and vice versa inside MongoDB aggregate map

I have the following document in a collection:

Input:

{
    "_id" : ObjectId("***"),
    "oldItems" : [ 
        {
            "_id" : ObjectId("***"),
            "name" : "ItemId***",
            "nestedItemsToExtract" : { }
        }
    ]
}

      

I need to iterate through an array oldItems

and create a resulting output document with another array whose values ​​are to be matched against the original.

Output:

{
    "_id" : ObjectId("***"),
    "newItems" : [ 
        {
            "oldItemId" : "***", // String Value Of Parent / Mapped Item Id aka ObjectId.toString()
            "_id" : ObjectId("***") // New ObjectId Here aka ObjectId()
        }
    ]
}

      

How can I convert the mapped (old) _id

ObjectId value to String, but generate a new ObjectId for the (new) property _id

in the resulting array?

Edit:

I was able to find a workaround to create a new ObjectId value using an expression "{ $literal: ObjectId() }"

. I have adjusted my Exit code snippet:

use DB_NAME_HERE

db.getCollection('COLLECTION_NAME_HERE').aggregate([
    { $match: {} },
    { $project: {
        newItems: {
            $map: {
                input: '$oldItems',
                as: 'oldItem',
                in: {
                    oldItemId: '$$oldItem._id' // Returns ObjectId
                    _id: ObjectId() // Fails With 'disallowed field type OID in object expression (at '_id')"'
                    //Edit
                    //_id: { $literal: ObjectId() } // Works
                }
            }
        }       
    }
}])

      

+3


source to share


1 answer


You cannot typecast from ObjectId to string (or vice vesa) in the aggregation pipeline in the current version of Mongodb (3.4). There are some issues with the official Mongodb bug tracker pointing to this issue:

SERVER-11400: Type conversion mechanism needed to convert between strings and numbers

SERVER-22781: Allow $ search between ObjectId (_id.str) and string



SERVER-24947: Type conversion mechanism needed for booleans, ISODates, ObjectID

As for the error while generating the ObjectId - try this:

use DB_NAME_HERE

db.getCollection('COLLECTION_NAME_HERE').aggregate([
    { $match: {} },
    { $project: {
        newItems: {
            $map: {
                input: '$oldItems',
                as: 'oldItem',
                in: {
                    oldItemId: '$$oldItem._id', // Returns ObjectId
                    _id: { $literal: ObjectId() }
                }
            }
        }       
    }
}])

      

+5


source







All Articles