diff --git a/devenv/docker/blocks/elasticstack/docker-compose.yaml b/devenv/docker/blocks/elasticstack/docker-compose.yaml index ad8a0d5e7f0..35b4254ac63 100644 --- a/devenv/docker/blocks/elasticstack/docker-compose.yaml +++ b/devenv/docker/blocks/elasticstack/docker-compose.yaml @@ -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 diff --git a/public/app/plugins/datasource/elasticsearch/datasource.test.ts b/public/app/plugins/datasource/elasticsearch/datasource.test.ts index 6b8d2606184..9cab4431395 100644 --- a/public/app/plugins/datasource/elasticsearch/datasource.test.ts +++ b/public/app/plugins/datasource/elasticsearch/datasource.test.ts @@ -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 () => { diff --git a/public/app/plugins/datasource/elasticsearch/datasource.ts b/public/app/plugins/datasource/elasticsearch/datasource.ts index 60623c04cd1..99b68fb3aa8 100644 --- a/public/app/plugins/datasource/elasticsearch/datasource.ts +++ b/public/app/plugins/datasource/elasticsearch/datasource.ts @@ -897,7 +897,11 @@ export class ElasticDatasource * Get values for a given field. * Used for example in getTagValues. */ - getTerms(queryDef: TermsQuery, range = getDefaultTimeRange()): Observable { + getTerms( + queryDef: TermsQuery, + range = getDefaultTimeRange(), + isTagValueQuery = false + ): Observable { 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) { - return lastValueFrom(this.getTerms({ field: options.key }, options.timeRange)); + return lastValueFrom(this.getTerms({ field: options.key }, options.timeRange, true)); } /**