O MongoDB 4.0 adiciona o
$convert
operador de agregação e o $toString
alias que permite que você faça exatamente isso:db.getCollection('example').aggregate([
{ "$match": { "example":1 } },
{ "$project": { "_id": { "$toString": "$_id" } } }
])
Um uso principal provavelmente seria usar o
_id
valor como uma "chave" em um documento. db.getCollection('example').insertOne({ "a": 1, "b": 2 })
db.getCollection('example').aggregate([
{ "$replaceRoot": {
"newRoot": {
"$arrayToObject": [
[{
"k": { "$toString": "$_id" },
"v": {
"$arrayToObject": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"cond": { "$ne": ["$$this.k", "_id"] }
}
}
}
}]
]
}
}}
])
Que retornaria:
{
"5b06973e7f859c325db150fd" : { "a" : 1, "b" : 2 }
}
O que mostra claramente a string, assim como o outro exemplo.
Geralmente, porém, geralmente há uma maneira de fazer "transformações" no cursor à medida que os documentos são retornados do servidor. Isso geralmente é uma coisa boa, pois um
ObjectId
é uma representação binária de 12 bytes em oposição a uma "string" hexadecimal de 24 caracteres que ocupa muito mais espaço. O shell tem um
.map()
método db.getCollection('example').find().map(d => Object.assign(d, { _id: d._id.valueOf() }) )
E o NodeJS tem um
Cursor.map()
que pode fazer a mesma coisa:let cursor = db.collection('example').find()
.map(( _id, ...d }) => ({ _id: _id.toString(), ...d }));
while ( await cursor.hasNext() ) {
let doc = cursor.next();
// do something
})
E o mesmo método também existe em outros drivers ( mas não no PHP ), ou você pode apenas iterar o cursor e transformar o conteúdo como é mais provável que seja a melhor coisa a fazer.
Na verdade, os resultados inteiros do cursor podem ser reduzidos em um único objeto com grande facilidade, simplesmente adicionando a qualquer instrução de retorno do cursor, ao trabalhar no shell
.toArray().reduce((o,e) => {
var _id = e._id;
delete e._id;
return Object.assign(o, { [_id]: e })
},{ })
Ou para ambientes completos de suporte a JavaScript ES6, como nodejs:
.toArray().reduce((o,({ _id, ...e })) => ({ ...o, [_id]: e }),{ })
Coisas realmente simples sem a complexidade do que precisa ser processado na estrutura de agregação. E muito possível em qualquer idioma pelos mesmos meios.