feat: add v10dev with default-aggregation and per-metric aggregation control - #202
Conversation
Add CDM v10dev with a new default-aggregation field on metric_desc that controls how metrics are aggregated across breakout dimensions. Four aggregation types are supported: sum — duration-weighted sum (current behavior, default fallback) avg — duration-weighted average divided by metric count max — maximum value across all metric documents min — minimum value across all metric documents The default-aggregation field is also accepted on v9dev for forward compatibility — post-processors can emit it before users switch to v10dev without breaking indexing. The aggregation dispatch is in calcAvg: getDefaultAggregation() queries the metric_desc for the field and the query template and result computation branch accordingly. Also fixes pre-existing regex bugs in getCdmVerFromIndex and getInstancesInfo that used [\d+] (single digit) instead of \d+ (one or more digits), which would have broken any multi-digit version. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add isValidCdmVersion() and cdmVersionOptionDesc() exports to cdm.js so all CLI scripts validate versions against the single supportedCdmVersions list instead of duplicating a regex and version enumeration in each file. Adding a new CDM version now only requires updating docTypes in cdm.js. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Allow users to override the default aggregation method at query time with --aggregation <sum|avg|max|min>. When specified, this takes priority over the default-aggregation value stored in the metric_desc document. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
k-rister
left a comment
There was a problem hiding this comment.
PR Review: CommonDataModel#202 — feat: add v10dev with default-aggregation and per-metric aggregation control
Summary: Adds CDM v10dev with a default-aggregation field on metric_desc that controls per-metric aggregation (sum/avg/max/min), adds --aggregation query-time override, consolidates version validation, and fixes pre-existing regex bugs.
Changed files: 12
Review dimensions: Correctness, API & Contracts, Build & Deploy, Documentation, Style
Issues
-
[cdm.js:3422]
sendMetricReqcallscalcAvgwith 7 args butcalcAvgnow takes 8 (missingdefaultAggregation) —calcAvg's signature was updated to(thisBegin, thisEnd, responses, jsonArrIdx, jsonArrTracker, numMetricIds, defaultAggregation, values)but the call insendMetricReqstill passesvalueSets[setIdx][trackerLabel]as the 7th arg, which lands indefaultAggregationinstead ofvalues. The actualvaluesparameter isundefined, sovalues.push(dataSample)would throw a TypeError. However,sendMetricReqis never called — it appears to be dead/legacy code fully superseded bygetMetricDataFromIdsSets. If it is truly dead code, consider removing it or adding the missingdefaultAggregationargument (e.g.,'sum') for correctness. Not blocking since the function is unreachable. -
[cdm.js:3645]
baseFiltervariable defined but never used — Thevar baseFilter = ...on line 3645 constructs a filter string using the initialthisBegin/thisEndvalues, but is never referenced — thefiltervariable inside thewhile (true)loop does the same construction with updated values. Dead code, likely a leftover from refactoring.
File Coverage
- VERSION — No issues (v8dev→v10dev; v9dev already existed in cdm.js)
- queries/cdmq/add-run-worker.js — No issues
- queries/cdmq/add-run.js — No issues
- queries/cdmq/cdm.js — 2 issues (sendMetricReq stale callsite, unused baseFilter)
- queries/cdmq/create-index.js — No issues
- queries/cdmq/delete-run.js — No issues
- queries/cdmq/get-instances-info.js — No issues
- queries/cdmq/get-metric-data.js — No issues
- queries/cdmq/get-primary-periods.js — No issues
- queries/cdmq/get-result-summary.js — No issues
- queries/cdmq/server.js — No issues
- templates/metric_desc.base — No issues
Limitations
- Cannot verify runtime behavior of max/min aggregation against live OpenSearch data
- Cannot verify that
esRequest(sync HTTP) ingetDefaultAggregationperforms acceptably under load — it blocks the Node.js event loop, but this matches the existing pattern used elsewhere in the codebase - The prettier reformatting accounts for a large portion of the diff; functional changes are concentrated in the aggregation dispatch logic
Verdict
Approve with comments — The aggregation dispatch logic is correct: query templates properly switch between weighted_avg/max/min aggregations, calcAvg handles partial-document boundary cases for both sum/avg and max/min paths, and the --aggregation override flows cleanly from CLI through server API to the query engine. The two issues (dead code in sendMetricReq, unused baseFilter) are non-blocking cleanup items. The version validation consolidation into isValidCdmVersion()/cdmVersionOptionDesc() is a clean refactor that eliminates the version enumeration duplication across 8 files. The regex fixes ([\d+] → \d+) are correct and address real bugs.
Fix sendMetricReq's calcAvg call to pass 'sum' as the defaultAggregation argument (legacy dead code, but correct the signature match). Remove unused baseFilter variable left over from query template refactoring. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Addressed
|
k-rister
left a comment
There was a problem hiding this comment.
PR Review: CommonDataModel#202 — re-review after aeab274
Both prior findings addressed in commit aeab274:
- ✅
sendMetricReqnow passes'sum'asdefaultAggregationtocalcAvg— signature match is correct - ✅ Unused
baseFiltervariable removed
No new issues introduced.
Verdict
Approve — All findings resolved; no new issues.
atheurer
left a comment
There was a problem hiding this comment.
PR Review: CommonDataModel #202
feat: add v10dev with default-aggregation and per-metric aggregation control
Overview
Solid PR. The core aggregation dispatch in calcAvg is correct — it properly switches OpenSearch query templates between weighted_avg, max, and min aggregations, and handles partial-document boundary cases appropriately for each mode. The version validation consolidation eliminates real maintenance burden across 8 files, and the regex fixes ([\d+] → \d+) fix genuine bugs that would have broken any future multi-digit CDM version.
~60% of the diff is prettier reformatting — the functional changes are concentrated in calcAvg, getMetricDataFromIdsSets, getMetricDataSets, and the v10dev index definitions.
Aggregation math verification
Traced the sum/avg/max/min logic:
- sum:
result = (aggAvgTimesWeight + sumValueTimesWeight) / totalWeightTimesMetrics * numMetricIds= total weighted value / timeWindowDuration. Correct — reconstructs the sum from the weighted average. - avg: same formula without the
* numMetricIdsmultiplication. Correct — gives the mean, not the total. - max/min: collects raw values from both aggregated and partial documents, applies
Math.max/Math.min. Correct — duration weighting is irrelevant for extrema.
Minor items (non-blocking)
-
Redundant
default-aggregationon v10dev — v9dev gets the field added, then v10dev is deep-cloned from v9dev (which now has it), then the same field is set again on v10dev. The second assignment is a no-op. Not a bug, but reads as though v10dev is adding something v9dev doesn't have. -
getDefaultAggregationdoesn't validate the stored value — garbage values in OpenSearch fall through to the weighted-avg path (safe default), but a log warning on unexpected values would catch misconfigured data early. -
q2(total_weight) sent for max/min — the total_weight query is always sent but unused for max/min. One extra OpenSearch request per time window per label. Probably not worth the complexity to skip conditionally. -
Hardcoded version dispatches —
getDocTypeandgetIndexBaseNamestill use|| cdmVer == 'v10dev'checks. When v11dev arrives these will need manual updates. Consider a helper or numeric comparison for future-proofing. -
Undocumented fix:
var cdmVeringetCdmVerFromIndex— previously an implicit global. Good catch, worth mentioning in the PR description.
What's good
- Forward compatibility is well thought out — v9dev gets the field too
- API validation is solid —
aggregationchecked against a whitelist - Version validation is DRY — adding a new version is a one-line change
- Regex fixes prevent real breakage
--aggregationoverride flows cleanly end-to-end
Approved ✅
- Remove redundant default-aggregation assignment on v10dev (already inherited from v9dev deep clone) - Add validation warning in getDefaultAggregation for unrecognized stored values (falls back to sum with log) - Replace hardcoded v9dev/v10dev checks in getDocType and getIndexBaseName with isValidCdmVersion() so future versions don't need manual dispatch updates Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Addressed (94dcb00)
Skipped
|
atheurer
left a comment
There was a problem hiding this comment.
Re-review: CommonDataModel #202 — after 94dcb00
All three items from my prior review are addressed:
- ✅ Redundant default-aggregation on v10dev — removed; comment updated to note inheritance via deep clone
- ✅ Unvalidated stored values —
getDefaultAggregationnow validates against['sum', 'avg', 'max', 'min']and logs a warning before falling back to sum - ✅ Hardcoded version dispatches —
getDocTypeandgetIndexBaseNamenow useisValidCdmVersion()instead of|| cdmVer == 'v10dev'. The v7dev/v8dev early-return guards correctly prevent double-matching.
No new issues introduced. Approved.
Summary
default-aggregationfield onmetric_descthat controls how metrics are aggregated across breakout dimensions — sum, avg, max, or min--aggregationquery-time override toget-metric-datafor ad-hoc analysis with a different aggregation methodisValidCdmVersion()andcdmVersionOptionDesc()helpers — adding future CDM versions only requires updatingdocTypesgetCdmVerFromIndexandgetInstancesInfothat would break any multi-digit version ([\d+]matched single digits only)Aggregation types
sumavgmaxminForward compatibility
The
default-aggregationfield is accepted on both v9dev and v10dev mappings. Post-processors can start emitting it before users switch to v10dev — the field is stored on v9dev and the aggregation dispatch works regardless of index version.Jira
PERFNFV-410 (under epic PERFNFV-409)
Test plan
default-aggregation, CDM sums latencies (24860); withdefault-aggregation: "max", CDM reports the max (4431)--aggregationoverride verified for all 4 types against the same indexed data--aggregationvalues return 400 error with clear messagedefault-aggregationfield accepted and aggregation works on v9dev datanode -csyntax check passes on all 12 changed filesprettier --checkpasses🤖 Generated with Claude Code