From 4b43785104ceeae3c091c630f909e00312bd18ba Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Fri, 4 Oct 2019 11:26:37 -0600 Subject: [PATCH 01/10] [Maps] Move sort out of top hits configuration for ES documents source --- .../legacy/plugins/maps/common/constants.js | 5 + .../es_search_source/es_search_source.js | 57 +++++--- .../es_search_source/update_source_editor.js | 130 +++++++++--------- 3 files changed, 113 insertions(+), 79 deletions(-) diff --git a/x-pack/legacy/plugins/maps/common/constants.js b/x-pack/legacy/plugins/maps/common/constants.js index 5af3f8cfc07149..33ad39adc5d1fb 100644 --- a/x-pack/legacy/plugins/maps/common/constants.js +++ b/x-pack/legacy/plugins/maps/common/constants.js @@ -39,6 +39,11 @@ export const LAYER_TYPE = { HEATMAP: 'HEATMAP' }; +export const SORT_ORDER = { + ASC: 'asc', + DESC: 'desc', +}; + export const EMS_TMS = 'EMS_TMS'; export const EMS_FILE = 'EMS_FILE'; export const ES_GEO_GRID = 'ES_GEO_GRID'; diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js index 071e231bb6e2da..4f8831d8d25dad 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js @@ -14,7 +14,7 @@ import { SearchSource } from '../../../kibana_services'; import { hitsToGeoJson } from '../../../elasticsearch_geo_utils'; import { CreateSourceEditor } from './create_source_editor'; import { UpdateSourceEditor } from './update_source_editor'; -import { ES_SEARCH, ES_GEO_FIELD_TYPE, ES_SIZE_LIMIT } from '../../../../common/constants'; +import { ES_SEARCH, ES_GEO_FIELD_TYPE, ES_SIZE_LIMIT, SORT_ORDER } from '../../../../common/constants'; import { i18n } from '@kbn/i18n'; import { getDataSourceLabel } from '../../../../common/i18n_getters'; import { ESTooltipProperty } from '../../tooltips/es_tooltip_property'; @@ -56,9 +56,10 @@ export class ESSearchSource extends AbstractESSource { geoField: descriptor.geoField, filterByMapBounds: _.get(descriptor, 'filterByMapBounds', DEFAULT_FILTER_BY_MAP_BOUNDS), tooltipProperties: _.get(descriptor, 'tooltipProperties', []), + sortField: _.get(descriptor, 'sortField', ''), + sortOrder: _.get(descriptor, 'sortOrder', SORT_ORDER.DESC), useTopHits: _.get(descriptor, 'useTopHits', false), topHitsSplitField: descriptor.topHitsSplitField, - topHitsTimeField: descriptor.topHitsTimeField, topHitsSize: _.get(descriptor, 'topHitsSize', 1), }, inspectorAdapters); } @@ -70,9 +71,10 @@ export class ESSearchSource extends AbstractESSource { onChange={onChange} filterByMapBounds={this._descriptor.filterByMapBounds} tooltipProperties={this._descriptor.tooltipProperties} + sortField={this._descriptor.sortField} + sortOrder={this._descriptor.sortOrder} useTopHits={this._descriptor.useTopHits} topHitsSplitField={this._descriptor.topHitsSplitField} - topHitsTimeField={this._descriptor.topHitsTimeField} topHitsSize={this._descriptor.topHitsSize} /> ); @@ -135,10 +137,24 @@ export class ESSearchSource extends AbstractESSource { ]; } + // Returns sort content for an Elasticsearch search body + _buildEsSort() { + const { + sortField, + sortOrder, + } = this._descriptor; + return [ + { + [sortField]: { + order: sortOrder + } + } + ]; + } + async _getTopHits(layerName, searchFilters, registerCancelCallback) { const { topHitsSplitField, - topHitsTimeField, topHitsSize, } = this._descriptor; @@ -158,7 +174,7 @@ export class ESSearchSource extends AbstractESSource { }); const searchSource = await this._makeSearchSource(searchFilters, 0); - searchSource.setField('aggs', { + const aggs = { entitySplit: { terms: { field: topHitsSplitField, @@ -167,13 +183,6 @@ export class ESSearchSource extends AbstractESSource { aggs: { entityHits: { top_hits: { - sort: [ - { - [topHitsTimeField]: { - order: 'desc' - } - } - ], _source: { includes: searchFilters.fieldNames }, @@ -183,7 +192,11 @@ export class ESSearchSource extends AbstractESSource { } } } - }); + }; + if (this._hasSort()) { + aggs.entitySplit.aggs.entityHits.top_hits.sort = this._buildEsSort(); + } + searchSource.setField('aggs', aggs); const resp = await this._runEsQuery(layerName, searchSource, registerCancelCallback, 'Elasticsearch document top hits request'); @@ -218,6 +231,10 @@ export class ESSearchSource extends AbstractESSource { // By setting "fields", SearchSource removes all of defaults searchSource.setField('fields', searchFilters.fieldNames); + if (this._hasSort()) { + searchSource.setField('sort', this._buildEsSort()); + } + const resp = await this._runEsQuery(layerName, searchSource, registerCancelCallback, 'Elasticsearch document request'); return { @@ -228,9 +245,16 @@ export class ESSearchSource extends AbstractESSource { }; } + // Returns true when top hits is enabled and properly configured _isTopHits() { - const { useTopHits, topHitsSplitField, topHitsTimeField } = this._descriptor; - return !!(useTopHits && topHitsSplitField && topHitsTimeField); + const { useTopHits, topHitsSplitField } = this._descriptor; + return !!(useTopHits && topHitsSplitField); + } + + // Returns true when sort is properly configured + _hasSort() { + const { sortField, sortOrder } = this._descriptor; + return !!(sortField && sortOrder); } async getGeoJsonWithMeta(layerName, searchFilters, registerCancelCallback) { @@ -406,9 +430,10 @@ export class ESSearchSource extends AbstractESSource { getSyncMeta() { return { + sortField: this._descriptor.sortField, + sortOrder: this._descriptor.sortOrder, useTopHits: this._descriptor.useTopHits, topHitsSplitField: this._descriptor.topHitsSplitField, - topHitsTimeField: this._descriptor.topHitsTimeField, topHitsSize: this._descriptor.topHitsSize, }; } diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js index ff319fd3d7e979..552d6e8c9a3fd4 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js @@ -6,7 +6,13 @@ import React, { Fragment, Component } from 'react'; import PropTypes from 'prop-types'; -import { EuiFormRow, EuiSwitch } from '@elastic/eui'; +import { + EuiFormRow, + EuiSwitch, + EuiFlexGroup, + EuiFlexItem, + EuiSelect, +} from '@elastic/eui'; import { SingleFieldSelect } from '../../../components/single_field_select'; import { TooltipSelector } from '../../../components/tooltip_selector'; @@ -14,6 +20,7 @@ import { indexPatternService } from '../../../kibana_services'; import { i18n } from '@kbn/i18n'; import { getTermsFields, getSourceFields } from '../../../index_pattern_util'; import { ValidatedRange } from '../../../components/validated_range'; +import { SORT_ORDER } from '../../../../common/constants'; export class UpdateSourceEditor extends Component { static propTypes = { @@ -21,16 +28,17 @@ export class UpdateSourceEditor extends Component { onChange: PropTypes.func.isRequired, filterByMapBounds: PropTypes.bool.isRequired, tooltipProperties: PropTypes.arrayOf(PropTypes.string).isRequired, + sortField: PropTypes.string, + sortOrder: PropTypes.string.isRequired, useTopHits: PropTypes.bool.isRequired, topHitsSplitField: PropTypes.string, - topHitsTimeField: PropTypes.string, topHitsSize: PropTypes.number.isRequired, }; state = { tooltipFields: null, termFields: null, - dateFields: null, + sortFields: null, }; componentDidMount() { @@ -64,27 +72,13 @@ export class UpdateSourceEditor extends Component { return; } - const dateFields = indexPattern.fields.filter(field => { - return field.type === 'date'; - }); - this.setState({ - dateFields, tooltipFields: getSourceFields(indexPattern.fields), termFields: getTermsFields(indexPattern.fields), + sortFields: indexPattern.fields.filter(field => { + return field.sortable; + }), }); - - if (!this.props.topHitsTimeField) { - // prefer default time field - if (indexPattern.timeFieldName) { - this.onTopHitsTimeFieldChange(indexPattern.timeFieldName); - } else { - // fall back to first date field in index - if (dateFields.length > 0) { - this.onTopHitsTimeFieldChange(dateFields[0].name); - } - } - } } _onTooltipPropertiesChange = propertyNames => { this.props.onChange({ propName: 'tooltipProperties', value: propertyNames }); @@ -102,10 +96,14 @@ export class UpdateSourceEditor extends Component { this.props.onChange({ propName: 'topHitsSplitField', value: topHitsSplitField }); }; - onTopHitsTimeFieldChange = topHitsTimeField => { - this.props.onChange({ propName: 'topHitsTimeField', value: topHitsTimeField }); + onSortFieldChange = sortField => { + this.props.onChange({ propName: 'sortField', value: sortField }); }; + onSortOrderChange = e => { + this.props.onChange({ propName: 'sortOrder', value: e.target.value }); + } + onTopHitsSizeChange = size => { this.props.onChange({ propName: 'topHitsSize', value: size }); }; @@ -115,31 +113,8 @@ export class UpdateSourceEditor extends Component { return null; } - let timeFieldSelect; let sizeSlider; if (this.props.topHitsSplitField) { - timeFieldSelect = ( - - - - ); - sizeSlider = ( - {timeFieldSelect} - {sizeSlider} ); } render() { - let topHitsCheckbox; - if (this.state.dateFields && this.state.dateFields.length) { - topHitsCheckbox = ( - - - - ); - } - return ( + + + + + + + + + + + - {topHitsCheckbox} + + + {this.renderTopHitsForm()} From 97370658c35c676a8c50e15da83432b2ad432466 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Fri, 4 Oct 2019 12:26:01 -0600 Subject: [PATCH 02/10] add migration script to convert topHitsTimeField to sortField --- .../migrations/top_hits_time_to_sort.js | 35 +++++++++++ .../migrations/top_hits_time_to_sort.test.js | 60 +++++++++++++++++++ x-pack/legacy/plugins/maps/migrations.js | 9 +++ 3 files changed, 104 insertions(+) create mode 100644 x-pack/legacy/plugins/maps/common/migrations/top_hits_time_to_sort.js create mode 100644 x-pack/legacy/plugins/maps/common/migrations/top_hits_time_to_sort.test.js diff --git a/x-pack/legacy/plugins/maps/common/migrations/top_hits_time_to_sort.js b/x-pack/legacy/plugins/maps/common/migrations/top_hits_time_to_sort.js new file mode 100644 index 00000000000000..7a72533005f478 --- /dev/null +++ b/x-pack/legacy/plugins/maps/common/migrations/top_hits_time_to_sort.js @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import _ from 'lodash'; +import { ES_SEARCH, SORT_ORDER } from '../constants'; + +function isEsDocumentSource(layerDescriptor) { + const sourceType = _.get(layerDescriptor, 'sourceDescriptor.type'); + return sourceType === ES_SEARCH; +} + +export function topHitsTimeToSort({ attributes }) { + if (!attributes.layerListJSON) { + return attributes; + } + + const layerList = JSON.parse(attributes.layerListJSON); + layerList.forEach((layerDescriptor) => { + if (isEsDocumentSource(layerDescriptor)) { + if (_.has(layerDescriptor, 'sourceDescriptor.topHitsTimeField')) { + layerDescriptor.sourceDescriptor.sortField = layerDescriptor.sourceDescriptor.topHitsTimeField; + layerDescriptor.sourceDescriptor.sortOrder = SORT_ORDER.DESC; + delete layerDescriptor.sourceDescriptor.topHitsTimeField; + } + } + }); + + return { + ...attributes, + layerListJSON: JSON.stringify(layerList), + }; +} diff --git a/x-pack/legacy/plugins/maps/common/migrations/top_hits_time_to_sort.test.js b/x-pack/legacy/plugins/maps/common/migrations/top_hits_time_to_sort.test.js new file mode 100644 index 00000000000000..09913e83cbb430 --- /dev/null +++ b/x-pack/legacy/plugins/maps/common/migrations/top_hits_time_to_sort.test.js @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +/* eslint max-len: 0 */ + +import { topHitsTimeToSort } from './top_hits_time_to_sort'; + +describe('topHitsTimeToSort', () => { + + test('Should handle missing layerListJSON attribute', () => { + const attributes = { + title: 'my map', + }; + expect(topHitsTimeToSort({ attributes })).toEqual({ + title: 'my map', + }); + }); + + test('Should move topHitsTimeField to sortField for ES documents sources', () => { + const layerListJSON = JSON.stringify([ + { + sourceDescriptor: { + type: 'ES_SEARCH', + topHitsSplitField: 'gpsId', + topHitsTimeField: '@timestamp', + } + } + ]); + const attributes = { + title: 'my map', + layerListJSON + }; + expect(topHitsTimeToSort({ attributes })).toEqual({ + title: 'my map', + layerListJSON: '[{\"sourceDescriptor\":{\"type\":\"ES_SEARCH\",\"topHitsSplitField\":\"gpsId\",\"sortField\":\"@timestamp\",\"sortOrder\":\"desc\"}}]', + }); + }); + + test('Should handle ES documents sources without topHitsTimeField', () => { + const layerListJSON = JSON.stringify([ + { + sourceDescriptor: { + type: 'ES_SEARCH', + topHitsSplitField: 'gpsId', + } + } + ]); + const attributes = { + title: 'my map', + layerListJSON + }; + expect(topHitsTimeToSort({ attributes })).toEqual({ + title: 'my map', + layerListJSON, + }); + }); +}); diff --git a/x-pack/legacy/plugins/maps/migrations.js b/x-pack/legacy/plugins/maps/migrations.js index 6a97636e679c42..cdec1f25ce2471 100644 --- a/x-pack/legacy/plugins/maps/migrations.js +++ b/x-pack/legacy/plugins/maps/migrations.js @@ -6,6 +6,7 @@ import { extractReferences } from './common/migrations/references'; import { emsRasterTileToEmsVectorTile } from './common/migrations/ems_raster_tile_to_ems_vector_tile'; +import { topHitsTimeToSort } from './common/migrations/top_hits_time_to_sort'; export const migrations = { 'map': { @@ -21,6 +22,14 @@ export const migrations = { '7.4.0': (doc) => { const attributes = emsRasterTileToEmsVectorTile(doc); + return { + ...doc, + attributes, + }; + }, + '7.5.0': (doc) => { + const attributes = topHitsTimeToSort(doc); + return { ...doc, attributes, From f03d4e4fd3a6f5248449c856ba72fae01d0e9768 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Fri, 4 Oct 2019 12:28:41 -0600 Subject: [PATCH 03/10] update i18n translations --- x-pack/plugins/translations/translations/ja-JP.json | 2 -- x-pack/plugins/translations/translations/zh-CN.json | 2 -- 2 files changed, 4 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index b7a6b242429243..46ca0417d5d729 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -5761,8 +5761,6 @@ "xpack.maps.source.esSearch.topHitsSizeLabel": "エンティティごとのドキュメント数", "xpack.maps.source.esSearch.topHitsSplitFieldLabel": "エンティティ", "xpack.maps.source.esSearch.topHitsSplitFieldSelectPlaceholder": "エンティティフィールドを選択", - "xpack.maps.source.esSearch.topHitsTimeFieldLabel": "時間", - "xpack.maps.source.esSearch.topHitsTimeFieldSelectPlaceholder": "タイムフィールドを選択", "xpack.maps.source.esSearch.useTopHitsLabel": "エンティティによる最も最近のドキュメントを表示", "xpack.maps.source.esSearchDescription": "Kibana インデックスパターンの地理空間データ", "xpack.maps.source.esSearchTitle": "ドキュメント", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 79cba3ee696be8..354db2b217ac68 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -5764,8 +5764,6 @@ "xpack.maps.source.esSearch.topHitsSizeLabel": "每个实体的文档", "xpack.maps.source.esSearch.topHitsSplitFieldLabel": "实体", "xpack.maps.source.esSearch.topHitsSplitFieldSelectPlaceholder": "选择实体字段", - "xpack.maps.source.esSearch.topHitsTimeFieldLabel": "时间", - "xpack.maps.source.esSearch.topHitsTimeFieldSelectPlaceholder": "选择时间字段", "xpack.maps.source.esSearch.useTopHitsLabel": "按实体显示最近的文档", "xpack.maps.source.esSearchDescription": "Kibana 索引模式的地理空间数据", "xpack.maps.source.esSearchTitle": "文档", From 2902b848184f13a2837ff24af80be1db4e3dce9c Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Fri, 4 Oct 2019 12:43:03 -0600 Subject: [PATCH 04/10] add jest test for es docs source UpdateSourceEditor component --- .../update_source_editor.test.js.snap | 292 ++++++++++++++++++ .../es_search_source/update_source_editor.js | 4 +- .../update_source_editor.test.js | 55 ++++ 3 files changed, 349 insertions(+), 2 deletions(-) create mode 100644 x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap create mode 100644 x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.test.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap new file mode 100644 index 00000000000000..6f50b9eaea2bcb --- /dev/null +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap @@ -0,0 +1,292 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should enable sort order select when sort field provided 1`] = ` + + + + + + + + + + + + + + + + + + + +`; + +exports[`should render top hits form when useTopHits is true 1`] = ` + + + + + + + + + + + + + + + + + + + + + + + + + +`; + +exports[`should render update source editor 1`] = ` + + + + + + + + + + + + + + + + + + + +`; diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js index 552d6e8c9a3fd4..ea7594423e3514 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js @@ -201,8 +201,8 @@ export class UpdateSourceEditor extends Component { ({})); + +import React from 'react'; +import { shallow } from 'enzyme'; + +import { UpdateSourceEditor } from './update_source_editor'; + +const defaultProps = { + indexPatternId: 'indexPattern1', + onChange: () => {}, + filterByMapBounds: true, + tooltipProperties: [], + sortOrder: 'DESC', + useTopHits: false, + topHitsSplitField: 'trackId', + topHitsSize: 1, +}; + +test('should render update source editor', async () => { + const component = shallow( + + ); + + expect(component).toMatchSnapshot(); +}); + +test('should enable sort order select when sort field provided', async () => { + const component = shallow( + + ); + + expect(component).toMatchSnapshot(); +}); + +test('should render top hits form when useTopHits is true', async () => { + const component = shallow( + + ); + + expect(component).toMatchSnapshot(); +}); From e2ef22fa5fd0e928f6f5e80a0411215e14441b53 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Fri, 4 Oct 2019 12:47:47 -0600 Subject: [PATCH 05/10] remove time configuration from top hits docs --- docs/maps/maps-aggregations.asciidoc | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/maps/maps-aggregations.asciidoc b/docs/maps/maps-aggregations.asciidoc index b953db8858c902..923b6cc1d6649a 100644 --- a/docs/maps/maps-aggregations.asciidoc +++ b/docs/maps/maps-aggregations.asciidoc @@ -36,8 +36,6 @@ To enable most recent entities, click "Show most recent documents by entity" and . Set *Entity* to the field that identifies entities in your documents. This field will be used in the terms aggregation to group your documents into entity buckets. -. Set *Time* to the date field that puts your documents in chronological order. -This field will be used to sort your documents in the top hits aggregation. . Set *Documents per entity* to configure the maximum number of documents accumulated per entity. [role="xpack"] From c545c0bf9608873b89044b6d3147ab5e7b51aaf5 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Fri, 4 Oct 2019 14:25:48 -0600 Subject: [PATCH 06/10] update migrations integration expect statement --- x-pack/test/api_integration/apis/maps/migrations.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/api_integration/apis/maps/migrations.js b/x-pack/test/api_integration/apis/maps/migrations.js index d8bdc5e61cb11b..e4ef5e57842492 100644 --- a/x-pack/test/api_integration/apis/maps/migrations.js +++ b/x-pack/test/api_integration/apis/maps/migrations.js @@ -42,7 +42,7 @@ export default function ({ getService }) { type: 'index-pattern' } ]); - expect(resp.body.migrationVersion).to.eql({ map: '7.4.0' }); + expect(resp.body.migrationVersion).to.eql({ map: '7.5.0' }); expect(resp.body.attributes.layerListJSON.includes('indexPatternRefName')).to.be(true); }); }); From 60284c5578b4bc52b5468c91d022bd756c5ab91a Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Mon, 7 Oct 2019 15:44:51 -0600 Subject: [PATCH 07/10] review feedback --- .../update_source_editor.test.js.snap | 44 +++++++++---------- .../es_search_source/es_search_source.js | 4 +- .../es_search_source/update_source_editor.js | 23 +++++----- 3 files changed, 34 insertions(+), 37 deletions(-) diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap index 6f50b9eaea2bcb..c0736a54e55d2a 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap @@ -64,8 +64,8 @@ exports[`should enable sort order select when sort field provided 1`] = ` labelType="label" > @@ -77,8 +77,8 @@ exports[`should enable sort order select when sort field provided 1`] = ` labelType="label" > @@ -149,20 +149,7 @@ exports[`should render top hits form when useTopHits is true 1`] = ` > - - - @@ -204,6 +191,19 @@ exports[`should render top hits form when useTopHits is true 1`] = ` value={1} /> + + + `; @@ -270,8 +270,8 @@ exports[`should render update source editor 1`] = ` labelType="label" > @@ -283,8 +283,8 @@ exports[`should render update source editor 1`] = ` labelType="label" > diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js index 4f8831d8d25dad..8fd2f49a8059d6 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js @@ -245,16 +245,14 @@ export class ESSearchSource extends AbstractESSource { }; } - // Returns true when top hits is enabled and properly configured _isTopHits() { const { useTopHits, topHitsSplitField } = this._descriptor; return !!(useTopHits && topHitsSplitField); } - // Returns true when sort is properly configured _hasSort() { const { sortField, sortOrder } = this._descriptor; - return !!(sortField && sortOrder); + return !!sortField && !!sortOrder; } async getGeoJsonWithMeta(layerName, searchFilters, registerCancelCallback) { diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js index ea7594423e3514..37c955c9821685 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js @@ -75,9 +75,7 @@ export class UpdateSourceEditor extends Component { this.setState({ tooltipFields: getSourceFields(indexPattern.fields), termFields: getTermsFields(indexPattern.fields), - sortFields: indexPattern.fields.filter(field => { - return field.sortable; - }), + sortFields: indexPattern.fields.filter(field => field.sortable), }); } _onTooltipPropertiesChange = propertyNames => { @@ -214,25 +212,26 @@ export class UpdateSourceEditor extends Component { + {this.renderTopHitsForm()} + - {this.renderTopHitsForm()} ); } From 249ac40c2954c4b122842a1f84dedb507700d4d2 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Mon, 7 Oct 2019 15:52:51 -0600 Subject: [PATCH 08/10] reverse hits list so top documents by sort are drawn on top --- .../layers/sources/es_search_source/es_search_source.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js index 8fd2f49a8059d6..53762a1f27d276 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js @@ -206,7 +206,7 @@ export class ESSearchSource extends AbstractESSource { entityBuckets.forEach(entityBucket => { const total = _.get(entityBucket, 'entityHits.hits.total', 0); const hits = _.get(entityBucket, 'entityHits.hits.hits', []); - // Reverse hits list so they are drawn from oldest to newest (per entity) so newest events are on top + // Reverse hits list so top documents by sort are drawn on top allHits.push(...hits.reverse()); if (total > hits.length) { hasTrimmedResults = true; @@ -238,7 +238,7 @@ export class ESSearchSource extends AbstractESSource { const resp = await this._runEsQuery(layerName, searchSource, registerCancelCallback, 'Elasticsearch document request'); return { - hits: resp.hits.hits, + hits: resp.hits.hits.reverse(), // Reverse hits so top documents by sort are drawn on top meta: { areResultsTrimmed: resp.hits.total > resp.hits.hits.length } From dd4824c00f6f9572778c4b1463914bd6d0c08a75 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 8 Oct 2019 08:04:17 -0600 Subject: [PATCH 09/10] update functional test expect to account for reversing hits order --- x-pack/test/functional/apps/maps/joins.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/maps/joins.js b/x-pack/test/functional/apps/maps/joins.js index 6e7541cc20db8e..251c5b90585acb 100644 --- a/x-pack/test/functional/apps/maps/joins.js +++ b/x-pack/test/functional/apps/maps/joins.js @@ -105,7 +105,7 @@ export default function ({ getPageObjects, getService }) { return feature.properties.__kbn__isvisible__; }); - expect(visibilitiesOfFeatures).to.eql([true, true, true, false]); + expect(visibilitiesOfFeatures).to.eql([false, true, true, true]); }); From 668992e5e898f33b41b5bc77680fd6cd5f893727 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 8 Oct 2019 09:23:03 -0600 Subject: [PATCH 10/10] update another functional test expect clause for reversing hits --- x-pack/test/functional/apps/maps/joins.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/maps/joins.js b/x-pack/test/functional/apps/maps/joins.js index 251c5b90585acb..41c777ad67c778 100644 --- a/x-pack/test/functional/apps/maps/joins.js +++ b/x-pack/test/functional/apps/maps/joins.js @@ -182,7 +182,7 @@ export default function ({ getPageObjects, getService }) { return feature.properties.__kbn__isvisible__; }); - expect(visibilitiesOfFeatures).to.eql([false, false, true, false]); + expect(visibilitiesOfFeatures).to.eql([false, true, false, false]); });