diff --git a/public/app/plugins/datasource/elasticsearch/datasource.ts b/public/app/plugins/datasource/elasticsearch/datasource.ts index 1e6b53ce25a..e0573bf5e22 100644 --- a/public/app/plugins/datasource/elasticsearch/datasource.ts +++ b/public/app/plugins/datasource/elasticsearch/datasource.ts @@ -344,6 +344,7 @@ export class ElasticDatasource extends DataSourceApi): Promise { + console.log('optinos', options); let payload = ''; const targets = _.cloneDeep(options.targets); const sentTargets: ElasticsearchQuery[] = []; @@ -411,6 +412,8 @@ export class ElasticDatasource extends DataSourceApi target.metrics.some(metric => metric.type === 'raw_document_v2'))) { + return er.getTimeSeries(true); } return er.getTimeSeries(); diff --git a/public/app/plugins/datasource/elasticsearch/elastic_response.ts b/public/app/plugins/datasource/elasticsearch/elastic_response.ts index 0dee3d727ac..3b556404eec 100644 --- a/public/app/plugins/datasource/elasticsearch/elastic_response.ts +++ b/public/app/plugins/datasource/elasticsearch/elastic_response.ts @@ -390,40 +390,90 @@ export class ElasticResponse { return result; } - getTimeSeries() { - const seriesList = []; + getTimeSeries(isV2 = false) { + if (isV2) { + const dataFrame: DataFrame[] = []; - for (let i = 0; i < this.response.responses.length; i++) { - const response = this.response.responses[i]; - if (response.error) { - throw this.getErrorFromElasticResponse(this.response, response.error); - } - - if (response.hits && response.hits.hits.length > 0) { - this.processHits(response.hits, seriesList); - } - - if (response.aggregations) { - const aggregations = response.aggregations; - const target = this.targets[i]; - const tmpSeriesList: any[] = []; - const table = new TableModel(); - - this.processBuckets(aggregations, target, tmpSeriesList, table, {}, 0); - this.trimDatapoints(tmpSeriesList, target); - this.nameSeries(tmpSeriesList, target); - - for (let y = 0; y < tmpSeriesList.length; y++) { - seriesList.push(tmpSeriesList[y]); + for (let n = 0; n < this.response.responses.length; n++) { + const response = this.response.responses[n]; + if (response.error) { + throw this.getErrorFromElasticResponse(this.response, response.error); } - if (table.rows.length > 0) { - seriesList.push(table); + if (response.hits && response.hits.hits.length > 0) { + const { propNames, docs } = flattenHits(response.hits.hits); + if (docs.length > 0) { + const series = createEmptyDataFrame(propNames, this.targets[0].timeField); + + // Add a row for each document + for (const doc of docs) { + series.add(doc); + } + + dataFrame.push(series); + } + } + + if (response.aggregations) { + const aggregations = response.aggregations; + const target = this.targets[n]; + const tmpSeriesList: any[] = []; + const table = new TableModel(); + + this.processBuckets(aggregations, target, tmpSeriesList, table, {}, 0); + this.trimDatapoints(tmpSeriesList, target); + this.nameSeries(tmpSeriesList, target); + + if (table.rows.length > 0) { + dataFrame.push(toDataFrame(table)); + } + + for (let y = 0; y < tmpSeriesList.length; y++) { + let series = toDataFrame(tmpSeriesList[y]); + + // When log results, show aggregations only in graph. Log fields are then going to be shown in table. + + dataFrame.push(series); + } } } + + return { data: dataFrame }; + } else { + const seriesList = []; + + for (let i = 0; i < this.response.responses.length; i++) { + const response = this.response.responses[i]; + if (response.error) { + throw this.getErrorFromElasticResponse(this.response, response.error); + } + + if (response.hits && response.hits.hits.length > 0) { + this.processHits(response.hits, seriesList); + } + + if (response.aggregations) { + const aggregations = response.aggregations; + const target = this.targets[i]; + const tmpSeriesList: any[] = []; + const table = new TableModel(); + + this.processBuckets(aggregations, target, tmpSeriesList, table, {}, 0); + this.trimDatapoints(tmpSeriesList, target); + this.nameSeries(tmpSeriesList, target); + + for (let y = 0; y < tmpSeriesList.length; y++) { + seriesList.push(tmpSeriesList[y]); + } + + if (table.rows.length > 0) { + seriesList.push(table); + } + } + } + + return { data: seriesList }; } - - return { data: seriesList }; } getLogs(logMessageField?: string, logLevelField?: string): DataQueryResponse { @@ -441,12 +491,6 @@ export class ElasticResponse { // Add a row for each document for (const doc of docs) { - if (logLevelField) { - // Remap level field based on the datasource config. This field is then used in explore to figure out the - // log level. We may rewrite some actual data in the level field if they are different. - doc['level'] = doc[logLevelField]; - } - series.add(doc); } diff --git a/public/app/plugins/datasource/elasticsearch/metric_agg.ts b/public/app/plugins/datasource/elasticsearch/metric_agg.ts index 0b51b6c0912..f90ae256894 100644 --- a/public/app/plugins/datasource/elasticsearch/metric_agg.ts +++ b/public/app/plugins/datasource/elasticsearch/metric_agg.ts @@ -106,6 +106,14 @@ export class ElasticMetricAggCtrl { $scope.settingsLinkText = 'Size: ' + $scope.agg.settings.size; $scope.target.metrics.splice(0, $scope.target.metrics.length, $scope.agg); + $scope.target.bucketAggs = []; + break; + } + case 'raw_document_v2': { + $scope.agg.settings.size = $scope.agg.settings.size || 500; + $scope.settingsLinkText = 'Size: ' + $scope.agg.settings.size; + $scope.target.metrics.splice(0, $scope.target.metrics.length, $scope.agg); + $scope.target.bucketAggs = []; break; } @@ -164,7 +172,10 @@ export class ElasticMetricAggCtrl { $scope.showOptions = false; // reset back to metric/group by query - if ($scope.target.bucketAggs.length === 0 && $scope.agg.type !== 'raw_document') { + if ( + ($scope.target.bucketAggs.length === 0 && $scope.agg.type !== 'raw_document') || + $scope.agg.type !== 'raw_document_v2' + ) { $scope.target.bucketAggs = [queryDef.defaultBucketAgg()]; } diff --git a/public/app/plugins/datasource/elasticsearch/query_builder.ts b/public/app/plugins/datasource/elasticsearch/query_builder.ts index fa61085685b..bb7644b0095 100644 --- a/public/app/plugins/datasource/elasticsearch/query_builder.ts +++ b/public/app/plugins/datasource/elasticsearch/query_builder.ts @@ -212,9 +212,10 @@ export class ElasticQueryBuilder { // If target doesn't have bucketAggs and type is not raw_document, it is invalid query. if (target.bucketAggs.length === 0) { metric = target.metrics[0]; - if (!metric || metric.type !== 'raw_document') { - throw { message: 'Invalid query' }; - } + //tu treba pridat + // if (!metric || metric.type !== 'raw_document') { + // throw { message: 'Invalid query' }; + // } } /* Handle document query: @@ -227,6 +228,14 @@ export class ElasticQueryBuilder { return this.documentQuery(query, size); } + /* Handle document query v2: + */ + if (target.metrics?.[0]?.type === 'raw_document_v2') { + metric = target.metrics[0]; + const size = (metric.settings && metric.settings.size !== 0 && metric.settings.size) || 500; + return this.documentQuery(query, size); + } + nestedAggs = query; for (i = 0; i < target.bucketAggs.length; i++) { diff --git a/public/app/plugins/datasource/elasticsearch/query_def.ts b/public/app/plugins/datasource/elasticsearch/query_def.ts index e85feadd360..5892fabd07b 100644 --- a/public/app/plugins/datasource/elasticsearch/query_def.ts +++ b/public/app/plugins/datasource/elasticsearch/query_def.ts @@ -80,6 +80,7 @@ export const metricAggTypes = [ minVersion: 2, }, { text: 'Raw Document', value: 'raw_document', requiresField: false }, + { text: 'Raw Document v2', value: 'raw_document_v2', requiresField: false }, { text: 'Logs', value: 'logs', requiresField: false }, ];