I need to get all the field names from my collection, including fields in subdocuments. I am currently running this command and getting only the names of the root fields. How can I get all field names?
My collection looks like this:
"UserId" : 11111,
"Personal" : {
"Email" : "[email protected]",
"FirstName" : "Name",
"LastName" : "Last"
},
"Car" : {
"CarType" : "NULL"
}
This is the command
var mr = db.runCommand({
"mapreduce" : "myCollection",
"map" : function() {
for (var key in this) { emit(key, null); }
},
"reduce" : function(key, stuff) { return null; },
"out": "myCollection" + "_keys"
})
db[mr.result].distinct("_id")
I want this result:
UserId, Personal.Email, Personal.FirstName, Personal.LastName, Car.CarType
In plain Javascript, you could take an iterative and recursive approach by looking at the object, their keys and their nested objects.
function getKeys(object) {
if (!object || typeof object !== 'object') {
return [];
}
if (Array.isArray(object)) {
return object.reduce((r, o) => [...r, ...getKeys(o)], []);
}
return Object.keys(object).reduce((r, k) => [...r, k, ...getKeys(object[k])], []);
}
var object = { UserId: 11111, Personal: { Email: "[email protected]", FirstName: "Name", LastName: "Last" }, Car: { CarType: "NULL" }, array: [{ foo: '', bar: '' }, { foo: '', bar: '' }] };
console.log(getKeys(object));
You can use below aggregation
db.collection.aggregate([
{ "$project": { "data": { "$objectToArray": "$$ROOT" }}},
{ "$project": {
"data": {
"$map": {
"input": "$data",
"in": {
"$cond": [
{ "$eq": [{ "$type": "$$this.v" }, "object"] },
{ "k": "$$this.k", "v": { "$objectToArray": "$$this.v" }},
"$$this"
]
}
}
}
}},
{ "$project": {
"data": {
"$map": {
"input": "$data",
"as": "d",
"in": {
"k": "$$d.k",
"v": {
"$map": {
"input": { "$cond": [{ "$eq": [{ "$type": "$$d.v" }, "array"] }, "$$d.v", []] },
"as": "v",
"in": { "v": { "$concat": ["$$d.k", ".", "$$v.k"] }}
}
}
}
}
}
}},
{ "$project": {
"finalKeys": {
"$concatArrays": [
{ "$reduce": {
"input": "$data.v",
"initialValue": [],
"in": { "$concatArrays": ["$$value", "$$this.v"] }
}},
"$data.k"
]
}
}}
])
Output
[
{
"finalKeys": [
"Personal.Email",
"Personal.FirstName",
"Personal.LastName",
"Car.CarType",
"_id",
"UserId",
"Personal",
"Car"
]
}
]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With