From f34509ff14f357a1b079c7063d999171d4b4da21 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Mon, 20 Apr 2020 10:50:54 -0600 Subject: [PATCH] [Maps] fix date labels (#63909) * [Maps] fix date labels * review feedback Co-authored-by: Elastic Machine --- .../maps/public/elasticsearch_geo_utils.js | 12 +++++++- .../public/elasticsearch_geo_utils.test.js | 29 +++++++++++++++---- .../es_search_source/es_search_source.js | 12 +++++++- .../properties/dynamic_style_property.js | 4 +++ 4 files changed, 49 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/maps/public/elasticsearch_geo_utils.js b/x-pack/plugins/maps/public/elasticsearch_geo_utils.js index 617cf537fd5c3..417c5d84f8916 100644 --- a/x-pack/plugins/maps/public/elasticsearch_geo_utils.js +++ b/x-pack/plugins/maps/public/elasticsearch_geo_utils.js @@ -64,7 +64,7 @@ function ensureGeometryType(type, expectedTypes) { * @param {string} geoFieldType Geometry field type ["geo_point", "geo_shape"] * @returns {number} */ -export function hitsToGeoJson(hits, flattenHit, geoFieldName, geoFieldType) { +export function hitsToGeoJson(hits, flattenHit, geoFieldName, geoFieldType, epochMillisFields) { const features = []; const tmpGeometriesAccumulator = []; @@ -80,6 +80,16 @@ export function hitsToGeoJson(hits, flattenHit, geoFieldName, geoFieldType) { geoShapeToGeometry(properties[geoFieldName], tmpGeometriesAccumulator); } + // There is a bug in Elasticsearch API where epoch_millis are returned as a string instead of a number + // https://github.com/elastic/elasticsearch/issues/50622 + // Convert these field values to integers. + for (let i = 0; i < epochMillisFields.length; i++) { + const fieldName = epochMillisFields[i]; + if (typeof properties[fieldName] === 'string') { + properties[fieldName] = parseInt(properties[fieldName]); + } + } + // don't include geometry field value in properties delete properties[geoFieldName]; diff --git a/x-pack/plugins/maps/public/elasticsearch_geo_utils.test.js b/x-pack/plugins/maps/public/elasticsearch_geo_utils.test.js index 5db7556be4639..fc02e19173843 100644 --- a/x-pack/plugins/maps/public/elasticsearch_geo_utils.test.js +++ b/x-pack/plugins/maps/public/elasticsearch_geo_utils.test.js @@ -66,7 +66,7 @@ describe('hitsToGeoJson', () => { }, }, ]; - const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point'); + const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point', []); expect(geojson.type).toBe('FeatureCollection'); expect(geojson.features.length).toBe(2); expect(geojson.features[0]).toEqual({ @@ -94,7 +94,7 @@ describe('hitsToGeoJson', () => { _source: {}, }, ]; - const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point'); + const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point', []); expect(geojson.type).toBe('FeatureCollection'); expect(geojson.features.length).toBe(1); }); @@ -111,7 +111,7 @@ describe('hitsToGeoJson', () => { }, }, ]; - const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point'); + const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point', []); expect(geojson.features.length).toBe(1); const feature = geojson.features[0]; expect(feature.properties.myField).toBe(8); @@ -128,7 +128,7 @@ describe('hitsToGeoJson', () => { }, }, ]; - const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point'); + const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point', []); expect(geojson.type).toBe('FeatureCollection'); expect(geojson.features.length).toBe(2); expect(geojson.features[0]).toEqual({ @@ -159,6 +159,23 @@ describe('hitsToGeoJson', () => { }); }); + it('Should convert epoch_millis value from string to integer', () => { + const hits = [ + { + _id: 'doc1', + _index: 'index1', + _source: { + [geoFieldName]: '20,100', + myDateField: '1587156257081', + }, + }, + ]; + const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point', ['myDateField']); + expect(geojson.type).toBe('FeatureCollection'); + expect(geojson.features.length).toBe(1); + expect(geojson.features[0].properties.myDateField).toBe(1587156257081); + }); + describe('dot in geoFieldName', () => { const indexPatternMock = { fields: { @@ -184,7 +201,7 @@ describe('hitsToGeoJson', () => { }, }, ]; - const geojson = hitsToGeoJson(hits, indexPatternFlattenHit, 'my.location', 'geo_point'); + const geojson = hitsToGeoJson(hits, indexPatternFlattenHit, 'my.location', 'geo_point', []); expect(geojson.features[0].geometry).toEqual({ coordinates: [100, 20], type: 'Point', @@ -199,7 +216,7 @@ describe('hitsToGeoJson', () => { }, }, ]; - const geojson = hitsToGeoJson(hits, indexPatternFlattenHit, 'my.location', 'geo_point'); + const geojson = hitsToGeoJson(hits, indexPatternFlattenHit, 'my.location', 'geo_point', []); expect(geojson.features[0].geometry).toEqual({ coordinates: [100, 20], type: 'Point', diff --git a/x-pack/plugins/maps/public/layers/sources/es_search_source/es_search_source.js b/x-pack/plugins/maps/public/layers/sources/es_search_source/es_search_source.js index 96679f0e85941..34fed37933e13 100644 --- a/x-pack/plugins/maps/public/layers/sources/es_search_source/es_search_source.js +++ b/x-pack/plugins/maps/public/layers/sources/es_search_source/es_search_source.js @@ -387,11 +387,21 @@ export class ESSearchSource extends AbstractESSource { }); return properties; }; + const epochMillisFields = searchFilters.fieldNames.filter(fieldName => { + const field = getField(indexPattern, fieldName); + return field.readFromDocValues && field.type === 'date'; + }); let featureCollection; try { const geoField = await this._getGeoField(); - featureCollection = hitsToGeoJson(hits, flattenHit, geoField.name, geoField.type); + featureCollection = hitsToGeoJson( + hits, + flattenHit, + geoField.name, + geoField.type, + epochMillisFields + ); } catch (error) { throw new Error( i18n.translate('xpack.maps.source.esSearch.convertToGeoJsonErrorMsg', { diff --git a/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js index ea521f8749d80..8cef78f9a8f21 100644 --- a/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js +++ b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js @@ -279,6 +279,10 @@ export class DynamicStyleProperty extends AbstractStyleProperty { } getNumericalMbFeatureStateValue(value) { + if (typeof value === 'number') { + return value; + } + const valueAsFloat = parseFloat(value); return isNaN(valueAsFloat) ? null : valueAsFloat; }