diff --git a/package.json b/package.json index 0bd114e..cd727e8 100644 --- a/package.json +++ b/package.json @@ -100,5 +100,5 @@ "engines": { "node": ">=16" }, - "packageManager": "yarn@" + "packageManager": "yarn@1.22.21" } diff --git a/src/datasource/OpenSearchResponse.ts b/src/datasource/OpenSearchResponse.ts index 7b51f18..d3adb0c 100644 --- a/src/datasource/OpenSearchResponse.ts +++ b/src/datasource/OpenSearchResponse.ts @@ -40,8 +40,9 @@ export class OpenSearchResponse { } switch (metric.type) { + case 'logs': case 'count': { - newSeries = { datapoints: [], metric: 'count', props, refId: target.refId }; + newSeries = { datapoints: [], metric: metric.type, props, refId: target.refId }; for (let i = 0; i < esAgg.buckets.length; i++) { const bucket = esAgg.buckets[i]; const value = bucket.doc_count; diff --git a/src/datasource/QueryBuilder.ts b/src/datasource/QueryBuilder.ts index b99abe9..dd990ae 100644 --- a/src/datasource/QueryBuilder.ts +++ b/src/datasource/QueryBuilder.ts @@ -444,6 +444,117 @@ export class QueryBuilder { // todo - use the limit variable to allow users to set this query = this.documentQuery(query, size || 500); + // If there are no bucket aggs to do here, then we don't need to do anything + // else + if (target.bucketAggs.length === 0) { + return { + ...query, + } + + } + + let i, j, pv, nestedAggs; + + nestedAggs = query; + + + for (i = 0; i < target.bucketAggs.length; i++) { + const aggDef = target.bucketAggs[i]; + const esAgg: any = {}; + + switch (aggDef.type) { + case 'date_histogram': { + esAgg['date_histogram'] = this.getDateHistogramAgg(aggDef); + break; + } + case 'histogram': { + esAgg['histogram'] = this.getHistogramAgg(aggDef); + break; + } + case 'filters': { + esAgg['filters'] = { filters: this.getFiltersAgg(aggDef) }; + break; + } + case 'terms': { + this.buildTermsAgg(aggDef, esAgg, target); + break; + } + case 'geohash_grid': { + esAgg['geohash_grid'] = { + field: aggDef.field, + precision: aggDef.settings?.precision, + }; + break; + } + } + + nestedAggs.aggs = nestedAggs.aggs || {}; + nestedAggs.aggs[aggDef.id] = esAgg; + nestedAggs = esAgg; + } + + nestedAggs.aggs = {}; + + for (i = 0; i < target.metrics.length; i++) { + metric = target.metrics[i]; + if (metric.type === 'count' || metric.type === "logs") { + continue; + } + + const aggField: any = {}; + let metricAgg: any = null; + + if (isPipelineAggregation(metric)) { + if (isPipelineAggregationWithMultipleBucketPaths(metric)) { + if (metric.pipelineVariables) { + metricAgg = { + buckets_path: {}, + }; + + for (j = 0; j < metric.pipelineVariables.length; j++) { + pv = metric.pipelineVariables[j]; + + if (pv.name && pv.pipelineAgg && /^\d*$/.test(pv.pipelineAgg)) { + const appliedAgg = findMetricById(target.metrics, pv.pipelineAgg); + if (appliedAgg) { + if (appliedAgg.type === 'count') { + metricAgg.buckets_path[pv.name] = '_count'; + } else { + metricAgg.buckets_path[pv.name] = pv.pipelineAgg; + } + } + } + } + } else { + continue; + } + } else { + if (metric.field && /^\d*$/.test(metric.field)) { + const appliedAgg = findMetricById(target.metrics, metric.field); + if (appliedAgg) { + if (appliedAgg.type === 'count') { + metricAgg = { buckets_path: '_count' }; + } else { + metricAgg = { buckets_path: metric.field }; + } + } + } else { + continue; + } + } + } else if (isMetricAggregationWithField(metric)) { + metricAgg = { field: metric.field }; + } + + metricAgg = { + ...metricAgg, + ...(isMetricAggregationWithSettings(metric) && metric.settings), + }; + + aggField[metric.type] = metricAgg; + nestedAggs.aggs[metric.id] = aggField; + } + return { ...query }; diff --git a/src/pages/explore.tsx b/src/pages/explore.tsx index 665cdda..8179359 100644 --- a/src/pages/explore.tsx +++ b/src/pages/explore.tsx @@ -134,12 +134,11 @@ class ResultStats extends SceneObjectBase { interface KaldbQueryState extends SceneObjectState { query: string; - timeseriesLoading: boolean; - logsLoading: boolean; + loading: boolean; } const KaldbQueryRenderer = ({ model }: SceneComponentProps) => { - const { timeseriesLoading, logsLoading } = model.useState(); + const { loading } = model.useState(); return ( <> @@ -155,12 +154,11 @@ const KaldbQueryRenderer = ({ model }: SceneComponentProps) => { onChange={(e) => model.onTextChange(e.currentTarget.value)} /> - {timeseriesLoading || logsLoading ? ( + {loading ? (