I have the following document in a collection:
Input:
{
"_id" : ObjectId("***"),
"oldItems" : [
{
"_id" : ObjectId("***"),
"name" : "ItemId***",
"nestedItemsToExtract" : { }
}
]
}
I need to iterate through the oldItems
array and create a resultant output document with another array, whose values should be mapped from the original one.
Output:
{
"_id" : ObjectId("***"),
"newItems" : [
{
"oldItemId" : "***", // String Value Of Parent's / Mapped Item Id aka ObjectId.toString()
"_id" : ObjectId("***") // New ObjectId Here aka ObjectId()
}
]
}
How to convert the mapped (old) _id
ObjectId value to a String, but generate a new ObjectId for the (new) _id
property in the resultant array?
Edit:
I have managed to find a workaround for generating a new ObjectId value via the "{ $literal: ObjectId() }"
expression. I have corrected my "Output" 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
}
}
}
}
}])
You can not do type conversion from ObjectId to string(or vice vesa) in an aggregation pipe-line in the current version of Mongodb(3.4). There are some issues on Mongodb official bug tracker pointing to that problem:
SERVER-11400: Need a type conversion mechanism to convert between strings and numbers
SERVER-22781: Allow $lookup between ObjectId (_id.str) and string
SERVER-24947: Need a type conversion mechanism for booleans, ISODates, ObjectID
As for an error during ObjectId generation - 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() }
}
}
}
}
}])