mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(tablepanel/elasticsearch): extended elasticsearch data source and query editor to support document queries
This commit is contained in:
parent
7d3146ed8d
commit
4e37290a7f
@ -14,8 +14,6 @@ transformers['timeseries_to_rows'] = {
|
||||
{text: 'Value'},
|
||||
];
|
||||
|
||||
model.rows = [];
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var series = data[i];
|
||||
for (var y = 0; y < series.datapoints.length; y++) {
|
||||
@ -31,8 +29,7 @@ transformers['timeseries_to_rows'] = {
|
||||
transformers['timeseries_to_columns'] = {
|
||||
description: 'Time series to columns',
|
||||
transform: function(data, panel, model) {
|
||||
model.columns = [{text: 'Time'}];
|
||||
model.rows = [];
|
||||
model.columns.push({text: 'Time'});
|
||||
|
||||
// group by time
|
||||
var points = {};
|
||||
@ -75,8 +72,19 @@ transformers['annotations'] = {
|
||||
|
||||
transformers['json'] = {
|
||||
description: 'JSON',
|
||||
transform: function(data, panel, model) {
|
||||
model.columns.push({text: 'JSON'});
|
||||
debugger;
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var series = data[i];
|
||||
|
||||
for (var y = 0; y < series.datapoints.length; y++) {
|
||||
var dp = series.datapoints[y];
|
||||
model.rows.push([JSON.stringify(dp)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export {transformers}
|
||||
|
||||
|
||||
|
@ -153,8 +153,8 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
||||
});
|
||||
};
|
||||
|
||||
ElasticDatasource.prototype.getQueryHeader = function(timeFrom, timeTo) {
|
||||
var header = {search_type: "count", "ignore_unavailable": true};
|
||||
ElasticDatasource.prototype.getQueryHeader = function(searchType, timeFrom, timeTo) {
|
||||
var header = {search_type: searchType, "ignore_unavailable": true};
|
||||
header.index = this.indexPattern.getIndexList(timeFrom, timeTo);
|
||||
return angular.toJson(header);
|
||||
};
|
||||
@ -163,8 +163,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
||||
var payload = "";
|
||||
var target;
|
||||
var sentTargets = [];
|
||||
|
||||
var header = this.getQueryHeader(options.range.from, options.range.to);
|
||||
var headerAdded = false;
|
||||
|
||||
for (var i = 0; i < options.targets.length; i++) {
|
||||
target = options.targets[i];
|
||||
@ -177,7 +176,14 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
||||
luceneQuery = luceneQuery.substr(1, luceneQuery.length - 2);
|
||||
esQuery = esQuery.replace("$lucene_query", luceneQuery);
|
||||
|
||||
payload += header + '\n' + esQuery + '\n';
|
||||
if (!headerAdded) {
|
||||
var searchType = queryObj.size === 0 ? 'count' : 'query_then_fetch';
|
||||
var header = this.getQueryHeader(searchType, options.range.from, options.range.to);
|
||||
payload += header + '\n';
|
||||
headerAdded = true;
|
||||
}
|
||||
|
||||
payload += esQuery + '\n';
|
||||
sentTargets.push(target);
|
||||
}
|
||||
|
||||
@ -230,7 +236,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
|
||||
|
||||
ElasticDatasource.prototype.getTerms = function(queryDef) {
|
||||
var range = timeSrv.timeRange();
|
||||
var header = this.getQueryHeader(range.from, range.to);
|
||||
var header = this.getQueryHeader('count', range.from, range.to);
|
||||
var esQuery = angular.toJson(this.queryBuilder.getTermsQuery(queryDef));
|
||||
|
||||
esQuery = esQuery.replace("$lucene_query", queryDef.query || '*');
|
||||
|
@ -173,6 +173,33 @@ function (_, queryDef) {
|
||||
}
|
||||
};
|
||||
|
||||
ElasticResponse.prototype.processHits = function(hits, seriesList) {
|
||||
var series = {target: 'docs', type: 'docs', datapoints: [], total: hits.total};
|
||||
var propName, hit, doc, i;
|
||||
|
||||
for (i = 0; i < hits.hits.length; i++) {
|
||||
hit = hits.hits[i];
|
||||
doc = {
|
||||
_id: hit._id,
|
||||
_type: hit._type,
|
||||
_index: hit._index
|
||||
};
|
||||
|
||||
if (hit._source) {
|
||||
for (propName in hit._source) {
|
||||
doc[propName] = hit._source[propName];
|
||||
}
|
||||
}
|
||||
|
||||
for (propName in hit.fields) {
|
||||
doc[propName] = hit.fields[propName];
|
||||
}
|
||||
series.datapoints.push(doc);
|
||||
}
|
||||
|
||||
seriesList.push(series);
|
||||
};
|
||||
|
||||
ElasticResponse.prototype.getTimeSeries = function() {
|
||||
var seriesList = [];
|
||||
|
||||
@ -182,15 +209,21 @@ function (_, queryDef) {
|
||||
throw { message: response.error };
|
||||
}
|
||||
|
||||
var aggregations = response.aggregations;
|
||||
var target = this.targets[i];
|
||||
var tmpSeriesList = [];
|
||||
if (response.hits) {
|
||||
this.processHits(response.hits, seriesList);
|
||||
}
|
||||
|
||||
this.processBuckets(aggregations, target, tmpSeriesList, {});
|
||||
this.nameSeries(tmpSeriesList, target);
|
||||
if (response.aggregations) {
|
||||
var aggregations = response.aggregations;
|
||||
var target = this.targets[i];
|
||||
var tmpSeriesList = [];
|
||||
|
||||
for (var y = 0; y < tmpSeriesList.length; y++) {
|
||||
seriesList.push(tmpSeriesList[y]);
|
||||
this.processBuckets(aggregations, target, tmpSeriesList, {});
|
||||
this.nameSeries(tmpSeriesList, target);
|
||||
|
||||
for (var y = 0; y < tmpSeriesList.length; y++) {
|
||||
seriesList.push(tmpSeriesList[y]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,6 +71,16 @@ function (angular) {
|
||||
return filterObj;
|
||||
};
|
||||
|
||||
ElasticQueryBuilder.prototype.documentQuery = function(query) {
|
||||
query.size = 500;
|
||||
query.sort = {};
|
||||
query.sort[this.timeField] = {order: 'desc', unmapped_type: 'boolean'};
|
||||
query.fields = ["*", "_source"];
|
||||
query.script_fields = {},
|
||||
query.fielddata_fields = [this.timeField];
|
||||
return query;
|
||||
};
|
||||
|
||||
ElasticQueryBuilder.prototype.build = function(target) {
|
||||
if (target.rawQuery) {
|
||||
return angular.fromJson(target.rawQuery);
|
||||
@ -96,6 +106,15 @@ function (angular) {
|
||||
}
|
||||
};
|
||||
|
||||
// handle document query
|
||||
if (target.bucketAggs.length === 0) {
|
||||
metric = target.metrics[0];
|
||||
if (metric && metric.type !== 'raw_document') {
|
||||
throw {message: 'Invalid query'};
|
||||
}
|
||||
return this.documentQuery(query, target);
|
||||
}
|
||||
|
||||
nestedAggs = query;
|
||||
|
||||
for (i = 0; i < target.bucketAggs.length; i++) {
|
||||
|
@ -108,7 +108,7 @@ describe('ElasticDatasource', function() {
|
||||
|
||||
it('should set size', function() {
|
||||
var body = angular.fromJson(parts[1]);
|
||||
expect(body.query.size).to.be(500);
|
||||
expect(body.size).to.be(500);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -411,4 +411,40 @@ describe('ElasticResponse', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Raw documents query', function() {
|
||||
beforeEach(function() {
|
||||
targets = [{ refId: 'A', metrics: [{type: 'raw_document', id: '1'}], bucketAggs: [] }];
|
||||
response = {
|
||||
responses: [{
|
||||
hits: {
|
||||
total: 100,
|
||||
hits: [
|
||||
{
|
||||
_id: '1',
|
||||
_type: 'type',
|
||||
_index: 'index',
|
||||
_source: {sourceProp: "asd"},
|
||||
fields: {fieldProp: "field" },
|
||||
},
|
||||
{
|
||||
_source: {sourceProp: "asd2"},
|
||||
fields: {fieldProp: "field2" },
|
||||
}
|
||||
]
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
result = new ElasticResponse(targets, response).getTimeSeries();
|
||||
});
|
||||
|
||||
it('should return docs', function() {
|
||||
expect(result.data.length).to.be(1);
|
||||
expect(result.data[0].type).to.be('docs');
|
||||
expect(result.data[0].total).to.be(100);
|
||||
expect(result.data[0].datapoints.length).to.be(2);
|
||||
expect(result.data[0].datapoints[0].sourceProp).to.be("asd");
|
||||
expect(result.data[0].datapoints[0].fieldProp).to.be("field");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -120,4 +120,14 @@ describe('ElasticQueryBuilder', function() {
|
||||
expect(query.aggs["2"].aggs["4"].date_histogram.field).to.be("@timestamp");
|
||||
});
|
||||
|
||||
it('with raw_document metric', function() {
|
||||
var query = builder.build({
|
||||
metrics: [{type: 'raw_document', id: '1'}],
|
||||
timeField: '@timestamp',
|
||||
bucketAggs: [],
|
||||
});
|
||||
|
||||
expect(query.size).to.be(500);
|
||||
});
|
||||
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user