And I want to query the DB to get the average (across records) of each field insidedata{} that starts with dem_num. Thus, the desired output of the query should be a javascript object with those averages:
Your life with aggregation will be so much easier.
Ok now the way to do the avg calculation might be a bit comlex since as far as I understand you don’t know all the field names up front. If you do now the field names then use a $project + ,$filter to remove any fields without the needed string . Then do an $unwind + $group + $avg on each of the fields on $data path.
If you don’t know the names of the fields you will need to play with $objectToArray operators to locate the field names as key and calculated the correct “v” avg.
If this is not clear I can try to provide an example later on
So asI mentioned the aggregation is not super easy and you should try and see if you can filter or stop at an early stage to optimise it for you.
Considering the given structure, here is an example of my aggregation:
db.collection.aggregate([{$project: {
// Make the data as a k, v of field names and values and regex on the needed starting pattern
data: {
$filter: {
input: {
$objectToArray: '$data'
},
as: 'dataItem',
cond: {
$regexMatch: {
input: '$$dataItem.k',
regex: RegExp('^dem_num')
}
}
}
}
}},
// Unwind so every item is an object
{$unwind: {
path: '$data'
}},
// group based on the keys and avg
{$group: {
_id: '$data.k',
avg: {
$avg: '$data.v.value'
}
}},
// Create a new key and value set to morph for object
{$group: {
_id: null,
root: {
$push: {
k: '$_id',
v: '$avg'
}
}
}},
// Create the new object
{$replaceRoot: {
newRoot: {
$arrayToObject: '$root'
}
}}])