Với MongoDB 3.4, bạn có thể sử dụng $objectToArray
và $arrayToObject
với $replaceRoot
để thay đổi điều này:
db.wish.aggregate([
{ "$replaceRoot": {
"newRoot": {
"$arrayToObject": {
"$concatArrays": [
[{ "k": "a", "v": "$a" }],
{ "$objectToArray": "$z" }
]
}
}
}}
])
Hoặc thậm chí câu chú dài này mà không cần chỉ định "a"
tài sản:
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"]
}}
]
}
}
}
}
}}
])
Cả hai đều sản xuất:
{ "a" : 1, "b" : 2, "c" : 3 }
Cách sử dụng thú vị của $concatArrays
không cần thiết trong các phiên bản sau vì sẽ có $mergeObjects
toán tử sẽ làm cho điều đó rõ ràng hơn một chút.
Nhưng về cơ bản bạn có thể làm điều tương tự trong mã khách hàng khá đơn giản. Ví dụ trong JavaScript cho shell:
db.wish.find().map( doc => (
Object.assign({ a: doc.a }, doc.z )
))
Hoặc phiên bản không có "a"
một lần nữa:
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),{})
)
Tạo ra cùng một đầu ra
{ "a" : 1, "b" : 2, "c" : 3 }