Elasticsearch: Fix adhoc filters with number fields (#99514)

pull/99568/head
Isabella Siu 4 months ago committed by GitHub
parent 53cc790180
commit 49f8359ce5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      devenv/docker/blocks/elasticstack/docker-compose.yaml
  2. 51
      public/app/plugins/datasource/elasticsearch/datasource.test.ts
  3. 13
      public/app/plugins/datasource/elasticsearch/datasource.ts

@ -5,6 +5,8 @@
- "discovery.type=single-node"
- "xpack.license.self_generated.type=basic"
- "xpack.security.enabled=false"
- 'ES_JAVA_OPTS=-XX:UseSVE=0'
- 'CLI_JAVA_OPTS=-XX:UseSVE=0'
ports:
- 9200:9200

@ -121,6 +121,48 @@ describe('ElasticDatasource', () => {
expect(gte).toBe('1663740610000'); // 2022-09-21T06:10:10Z
expect(lte).toBe('1663999821000'); // 2022-09-24T06:10:21Z
});
it('should return fields properly', async () => {
const ds = createElasticDatasource({ jsonData: { timeField: '@timestamp' } });
const getTagValuesData = {
responses: [
{
aggregations: {
'1': {
buckets: [
{
doc_count: 10,
key: 'foo',
},
{
doc_count: 20,
key: 6,
key_as_string: 'six',
},
{
doc_count: 30,
key: 7,
},
],
},
},
},
],
};
const postResource = jest.spyOn(ds, 'postResourceRequest').mockResolvedValue(getTagValuesData);
const values = await ds.getTagValues({ key: 'test', timeRange: timeRangeMock, filters: [] });
expect(postResource).toHaveBeenCalledTimes(1);
expect(values.length).toBe(3);
expect(values[0].text).toBe('foo');
expect(values[0].value).toBe('foo');
expect(values[1].text).toBe('six');
expect(values[1].value).toBe('6');
expect(values[2].text).toBe('7');
expect(values[2].value).toBe('7');
});
});
describe('query', () => {
@ -1078,6 +1120,10 @@ describe('ElasticDatasource', () => {
key: 'test2',
key_as_string: 'test2_as_string',
},
{
doc_count: 2,
key: 5,
},
],
},
},
@ -1102,13 +1148,14 @@ describe('ElasticDatasource', () => {
it('should get results', async () => {
const { results } = await runScenario();
expect(results.length).toEqual(2);
expect(results.length).toEqual(3);
});
it('should use key or key_as_string', async () => {
it('should use key, key_as_string, or cast key to string', async () => {
const { results } = await runScenario();
expect(results[0].text).toEqual('test');
expect(results[1].text).toEqual('test2_as_string');
expect(results[2].text).toEqual('5');
});
it('should not set search type to count', async () => {

@ -897,7 +897,11 @@ export class ElasticDatasource
* Get values for a given field.
* Used for example in getTagValues.
*/
getTerms(queryDef: TermsQuery, range = getDefaultTimeRange()): Observable<MetricFindValue[]> {
getTerms(
queryDef: TermsQuery,
range = getDefaultTimeRange(),
isTagValueQuery = false
): Observable<MetricFindValue[]> {
const searchType = 'query_then_fetch';
const header = this.getQueryHeader(searchType, range.from, range.to);
let esQuery = JSON.stringify(this.queryBuilder.getTermsQuery(queryDef));
@ -919,9 +923,10 @@ export class ElasticDatasource
const buckets = res.responses[0].aggregations['1'].buckets;
return _map(buckets, (bucket) => {
const keyString = String(bucket.key);
return {
text: bucket.key_as_string || bucket.key,
value: bucket.key,
text: bucket.key_as_string || keyString,
value: isTagValueQuery ? keyString : bucket.key,
};
});
})
@ -979,7 +984,7 @@ export class ElasticDatasource
* @returns A Promise that resolves to an array of label values represented as MetricFindValue objects
*/
getTagValues(options: DataSourceGetTagValuesOptions<ElasticsearchQuery>) {
return lastValueFrom(this.getTerms({ field: options.key }, options.timeRange));
return lastValueFrom(this.getTerms({ field: options.key }, options.timeRange, true));
}
/**

Loading…
Cancel
Save