在 MongoDB 聚合映射中将 ObjectId 转换为 String,反之亦然

Convert ObjectId to String and vice versa inside MongoDB aggregate map

我在 collection 中有以下文档:

输入:

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

我需要遍历 oldItems 数组并使用另一个数组创建结果输出文档,其值应从原始数组映射而来。

输出:

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

如何将映射的(旧)_id ObjectId 值转换为字符串,但为结果数组中的(新)_id 属性 生成新的 ObjectId?

编辑:

我设法找到了一种通过 "{ $literal: ObjectId() }" 表达式生成新 ObjectId 值的解决方法。我已经更正了我的 "Output" 代码片段:

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
                }
            }
        }       
    }
}])

在当前版本的 Mongodb(3.4) 中,您无法在聚合管道中进行从 ObjectId 到字符串(或反之亦然)的类型转换。 Mongodb 官方错误跟踪器上有一些问题指向该问题:

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

至于 ObjectId 生成期间的错误 - 试试这个:

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