Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert ObjectId to String and vice versa inside MongoDB aggregate map

Tags:

mongodb

robo3t

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
                }
            }
        }       
    }
}])
like image 352
Mikhail Avatar asked Apr 04 '17 11:04

Mikhail


People also ask

How to convert ObjectId into string?

In Mongoose, you can use toString() method on ObjectId to get a 24-character hexadecimal string.

How to convert ObjectId to string in java?

This worked for me: String objectId = (String) result. get("_id. $oid");


1 Answers

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() }
                }
            }
        }       
    }
}])
like image 160
Filipp Shestakov Avatar answered Oct 17 '22 18:10

Filipp Shestakov