Penso che il modo migliore per farlo, come menzionato qui, sia nel mongod 3.4.4+, ma senza usare l' $unwind
operatore e usare solo due fasi nella pipeline. Invece possiamo usare gli operatori $mergeObjects
e $objectToArray
.
Nella $group
fase, utilizziamo l' $mergeObjects
operatore per restituire un singolo documento in cui chiave / valore provengono da tutti i documenti della raccolta.
Quindi arriva il $project
luogo in cui utilizziamo $map
e $objectToArray
restituiamo le chiavi.
let allTopLevelKeys = [
{
"$group": {
"_id": null,
"array": {
"$mergeObjects": "$$ROOT"
}
}
},
{
"$project": {
"keys": {
"$map": {
"input": { "$objectToArray": "$array" },
"in": "$$this.k"
}
}
}
}
];
Ora se abbiamo documenti nidificati e vogliamo ottenere anche le chiavi, questo è fattibile. Per semplicità, consideriamo un documento con un semplice documento incorporato simile al seguente:
{field1: {field2: "abc"}, field3: "def"}
{field1: {field3: "abc"}, field4: "def"}
La seguente pipeline fornisce tutte le chiavi (field1, field2, field3, field4).
let allFistSecondLevelKeys = [
{
"$group": {
"_id": null,
"array": {
"$mergeObjects": "$$ROOT"
}
}
},
{
"$project": {
"keys": {
"$setUnion": [
{
"$map": {
"input": {
"$reduce": {
"input": {
"$map": {
"input": {
"$objectToArray": "$array"
},
"in": {
"$cond": [
{
"$eq": [
{
"$type": "$$this.v"
},
"object"
]
},
{
"$objectToArray": "$$this.v"
},
[
"$$this"
]
]
}
}
},
"initialValue": [
],
"in": {
"$concatArrays": [
"$$this",
"$$value"
]
}
}
},
"in": "$$this.k"
}
}
]
}
}
}
]
Con un piccolo sforzo, possiamo ottenere la chiave per tutti i documenti secondari in un campo di array in cui anche gli elementi sono oggetti.