Con MongoDB 3.4 puoi usare $objectToArray
e $arrayToObject
con $replaceRoot
per cambiarlo:
db.wish.aggregate([
{ "$replaceRoot": {
"newRoot": {
"$arrayToObject": {
"$concatArrays": [
[{ "k": "a", "v": "$a" }],
{ "$objectToArray": "$z" }
]
}
}
}}
])
O anche questo lungo incantesimo senza nemmeno specificare il "a"
proprietà:
db.wish.aggregate([
{ "$replaceRoot": {
"newRoot": {
"$arrayToObject": {
"$reduce": {
"input": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "r",
"cond": { "$ne": [ "$$r.k", "_id" ] }
}
},
"initialValue": [],
"in": {
"$concatArrays": [
"$$value",
{ "$cond": {
"if": { "$gt": [ "$$this.v", {} ] },
"then": { "$objectToArray": "$$this.v" },
"else": ["$$this"]
}}
]
}
}
}
}
}}
])
Entrambi producono:
{ "a" : 1, "b" : 2, "c" : 3 }
L'uso divertente di $concatArrays
non dovrebbe essere necessario nelle versioni future poiché ci sarà un $mergeObjects
operatore che lo renderà un po' più pulito.
Ma in pratica puoi semplicemente fare la stessa cosa nel codice client in modo abbastanza semplice. Ad esempio in JavaScript per la shell:
db.wish.find().map( doc => (
Object.assign({ a: doc.a }, doc.z )
))
O la versione senza il "a"
ancora:
db.wish.find().map( doc =>
Object.keys(doc).filter(k => k !== '_id').map(k =>
( typeof(doc[k]) === "object" ) ?
Object.keys(doc[k]).map(i => ({ [i]: doc[k][i] }))
.reduce((acc, curr) => Object.assign(acc,curr),{})
: { [k]: doc[k] }
).reduce((acc,curr) => Object.assign(acc,curr),{})
)
Produce lo stesso output
{ "a" : 1, "b" : 2, "c" : 3 }