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
}
}
}
}
}])
source to share
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() }
}
}
}
}
}])
source to share