Ich denke, der beste Weg, dies wie hier erwähnt zu tun , ist in Mongod 3.4.4+, aber ohne den $unwind
Operator zu verwenden und nur zwei Stufen in der Pipeline zu verwenden. Stattdessen können wir die Operatoren $mergeObjects
und verwenden $objectToArray
.
In der $group
Phase verwenden wir den $mergeObjects
Operator, um ein einzelnes Dokument zurückzugeben, bei dem Schlüssel / Wert aus allen Dokumenten in der Sammlung stammen.
Dann kommt der Ort, an $project
dem wir die Schlüssel verwenden $map
und $objectToArray
zurückgeben.
let allTopLevelKeys = [
{
"$group": {
"_id": null,
"array": {
"$mergeObjects": "$$ROOT"
}
}
},
{
"$project": {
"keys": {
"$map": {
"input": { "$objectToArray": "$array" },
"in": "$$this.k"
}
}
}
}
];
Wenn wir nun verschachtelte Dokumente haben und auch die Schlüssel erhalten möchten, ist dies machbar. Betrachten Sie der Einfachheit halber ein Dokument mit einem einfachen eingebetteten Dokument, das folgendermaßen aussieht:
{field1: {field2: "abc"}, field3: "def"}
{field1: {field3: "abc"}, field4: "def"}
Die folgende Pipeline liefert alle Schlüssel (Feld1, Feld2, Feld3, Feld4).
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"
}
}
]
}
}
}
]
Mit ein wenig Aufwand können wir den Schlüssel für alle Unterdokumente in einem Array-Feld abrufen, in dem die Elemente ebenfalls Objekte sind.