[maps] remove IVectorSource.getFieldNames (#159747)

`IVectorSource` interface has many similar sounding methods that are
used for different purposes. These lead to confusion and an unclear API
* getFieldNames
* getFields
* getFieldByName

Although `getFieldNames` sounds similar to `getFields`, the 2 are used
for very different purposes.
* getFieldNames returns a string array that is used to trigger source
re-fetch
* getFields returns an array of fields to drive UI such as field
selection for data driven styling

`getFieldNames` overlaps 100% in functionality with `getSyncMeta` and is
not needed. Combining output of `getFieldNames` into `getSyncMeta`
simplifies the `IVectorSource` API and removes some confusion.

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Nathan Reese 2023-06-27 11:36:43 -06:00 committed by GitHub
parent 8bbfeef0a3
commit 2fb4d5fff8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 113 additions and 118 deletions

View file

@ -106,10 +106,6 @@ export class CustomRasterSource implements IRasterSource {
return false; return false;
} }
getFieldNames(): string[] {
return [];
}
renderSourceSettingsEditor(sourceEditorArgs: SourceEditorArgs): ReactElement<any> | null { renderSourceSettingsEditor(sourceEditorArgs: SourceEditorArgs): ReactElement<any> | null {
return null; return null;
} }

View file

@ -46,6 +46,9 @@ export type SourceRequestMeta = DataFilters & {
}; };
export type VectorSourceRequestMeta = SourceRequestMeta & { export type VectorSourceRequestMeta = SourceRequestMeta & {
/*
* List of feature property keys used in client for data driven styling, join keys, and feature masking
*/
fieldNames: string[]; fieldNames: string[];
timesliceMaskField?: string; timesliceMaskField?: string;
sourceMeta: object | null; sourceMeta: object | null;

View file

@ -100,7 +100,7 @@ export class HeatmapLayer extends AbstractLayer {
prevDataRequest: this.getSourceDataRequest(), prevDataRequest: this.getSourceDataRequest(),
requestMeta: buildVectorRequestMeta( requestMeta: buildVectorRequestMeta(
this.getSource(), this.getSource(),
this.getSource().getFieldNames(), [], // fieldNames is empty because heatmap layer only support metrics
syncContext.dataFilters, syncContext.dataFilters,
this.getQuery(), this.getQuery(),
syncContext.isForceRefresh, syncContext.isForceRefresh,

View file

@ -51,6 +51,7 @@ import {
import { IVectorSource } from '../../sources/vector_source'; import { IVectorSource } from '../../sources/vector_source';
import { LayerIcon, ILayer } from '../layer'; import { LayerIcon, ILayer } from '../layer';
import { InnerJoin } from '../../joins/inner_join'; import { InnerJoin } from '../../joins/inner_join';
import { isSpatialJoin } from '../../joins/is_spatial_join';
import { IField } from '../../fields/field'; import { IField } from '../../fields/field';
import { DataRequestContext } from '../../../actions'; import { DataRequestContext } from '../../../actions';
import { ITooltipProperty } from '../../tooltips/tooltip_property'; import { ITooltipProperty } from '../../tooltips/tooltip_property';
@ -354,9 +355,12 @@ export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer {
isFeatureEditorOpenForLayer: boolean isFeatureEditorOpenForLayer: boolean
): Promise<VectorSourceRequestMeta> { ): Promise<VectorSourceRequestMeta> {
const fieldNames = [ const fieldNames = [
...source.getFieldNames(),
...style.getSourceFieldNames(), ...style.getSourceFieldNames(),
...this.getValidJoins().map((join) => join.getLeftField().getName()), ...this.getValidJoins()
.filter((join) => {
return !isSpatialJoin(join.toDescriptor());
})
.map((join) => join.getLeftField().getName()),
]; ];
const timesliceMaskFieldName = await source.getTimesliceMaskFieldName(); const timesliceMaskFieldName = await source.getTimesliceMaskFieldName();
@ -550,7 +554,7 @@ export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer {
const joinRequestMeta = buildVectorRequestMeta( const joinRequestMeta = buildVectorRequestMeta(
joinSource, joinSource,
joinSource.getFieldNames(), [], // fieldNames is empty because join sources only support metrics
dataFilters, dataFilters,
joinSource.getWhereQuery(), joinSource.getWhereQuery(),
isForceRefresh, isForceRefresh,

View file

@ -8,12 +8,16 @@
import { i18n } from '@kbn/i18n'; import { i18n } from '@kbn/i18n';
import { GeoJsonProperties } from 'geojson'; import { GeoJsonProperties } from 'geojson';
import { DataView } from '@kbn/data-plugin/common'; import { DataView } from '@kbn/data-plugin/common';
import type { IESAggSource } from './types'; import type { IESAggSource, ESAggsSourceSyncMeta } from './types';
import { AbstractESSource } from '../es_source'; import { AbstractESSource } from '../es_source';
import { esAggFieldsFactory, IESAggField } from '../../fields/agg'; import { esAggFieldsFactory, IESAggField } from '../../fields/agg';
import { AGG_TYPE, FIELD_ORIGIN } from '../../../../common/constants'; import { AGG_TYPE, FIELD_ORIGIN } from '../../../../common/constants';
import { getSourceAggKey } from '../../../../common/get_agg_key'; import { getSourceAggKey } from '../../../../common/get_agg_key';
import { AbstractESAggSourceDescriptor, AggDescriptor } from '../../../../common/descriptor_types'; import {
AbstractESAggSourceDescriptor,
AggDescriptor,
DataFilters,
} from '../../../../common/descriptor_types';
import { IField } from '../../fields/field'; import { IField } from '../../fields/field';
import { ITooltipProperty } from '../../tooltips/tooltip_property'; import { ITooltipProperty } from '../../tooltips/tooltip_property';
import { getAggDisplayName } from './get_agg_display_name'; import { getAggDisplayName } from './get_agg_display_name';
@ -142,6 +146,23 @@ export abstract class AbstractESAggSource extends AbstractESSource implements IE
return false; return false;
} }
/*
* Changes in requestMeta.fieldNames does not require re-fetch.
* It is not possible to filter metrics from responses so all metrics are always returned in all responses.
*/
isFieldAware(): boolean {
return false;
}
/*
* Force re-fetch when requested metrics change.
*/
getSyncMeta(dataFilters: DataFilters): ESAggsSourceSyncMeta {
return {
metrics: this.getMetricFields().map((esAggMetricField) => esAggMetricField.getName()),
};
}
getGeoGridPrecision(zoom: number): number { getGeoGridPrecision(zoom: number): number {
return 0; return 0;
} }

View file

@ -5,6 +5,6 @@
* 2.0. * 2.0.
*/ */
export type { IESAggSource } from './types'; export type { IESAggSource, ESAggsSourceSyncMeta } from './types';
export { AbstractESAggSource, DEFAULT_METRIC } from './es_agg_source'; export { AbstractESAggSource, DEFAULT_METRIC } from './es_agg_source';
export { getAggDisplayName } from './get_agg_display_name'; export { getAggDisplayName } from './get_agg_display_name';

View file

@ -25,3 +25,7 @@ export interface IESAggSource extends IESSource {
isGeoGridPrecisionAware(): boolean; isGeoGridPrecisionAware(): boolean;
getGeoGridPrecision(zoom: number): number; getGeoGridPrecision(zoom: number): number;
} }
export interface ESAggsSourceSyncMeta {
metrics: string[];
}

View file

@ -35,7 +35,7 @@ import {
} from '../../../../common/constants'; } from '../../../../common/constants';
import { getDataSourceLabel, getDataViewLabel } from '../../../../common/i18n_getters'; import { getDataSourceLabel, getDataViewLabel } from '../../../../common/i18n_getters';
import { buildGeoGridFilter } from '../../../../common/elasticsearch_util'; import { buildGeoGridFilter } from '../../../../common/elasticsearch_util';
import { AbstractESAggSource } from '../es_agg_source'; import { AbstractESAggSource, ESAggsSourceSyncMeta } from '../es_agg_source';
import { DataRequestAbortError } from '../../util/data_request'; import { DataRequestAbortError } from '../../util/data_request';
import { LICENSED_FEATURES } from '../../../licensed_features'; import { LICENSED_FEATURES } from '../../../licensed_features';
@ -56,11 +56,10 @@ import { isMvt } from './is_mvt';
import { VectorStyle } from '../../styles/vector/vector_style'; import { VectorStyle } from '../../styles/vector/vector_style';
import { getIconSize } from './get_icon_size'; import { getIconSize } from './get_icon_size';
interface ESGeoGridSourceSyncMeta { type ESGeoGridSourceSyncMeta = ESAggsSourceSyncMeta &
geogridPrecision: number; Pick<ESGeoGridSourceDescriptor, 'requestType' | 'resolution'> & {
requestType: RENDER_AS; geogridPrecision: number;
resolution: GRID_RESOLUTION; };
}
const MAX_GEOTILE_LEVEL = 29; const MAX_GEOTILE_LEVEL = 29;
@ -160,6 +159,7 @@ export class ESGeoGridSource extends AbstractESAggSource implements IMvtVectorSo
getSyncMeta(dataFilters: DataFilters): ESGeoGridSourceSyncMeta { getSyncMeta(dataFilters: DataFilters): ESGeoGridSourceSyncMeta {
return { return {
...super.getSyncMeta(dataFilters),
geogridPrecision: this.getGeoGridPrecision(dataFilters.zoom), geogridPrecision: this.getGeoGridPrecision(dataFilters.zoom),
requestType: this._descriptor.requestType, requestType: this._descriptor.requestType,
resolution: this._descriptor.resolution, resolution: this._descriptor.resolution,
@ -189,10 +189,6 @@ export class ESGeoGridSource extends AbstractESAggSource implements IMvtVectorSo
return isMvt(this._descriptor.requestType, this._descriptor.resolution); return isMvt(this._descriptor.requestType, this._descriptor.resolution);
} }
getFieldNames() {
return this.getMetricFields().map((esAggMetricField) => esAggMetricField.getName());
}
isGeoGridPrecisionAware(): boolean { isGeoGridPrecisionAware(): boolean {
if (this.isMvt()) { if (this.isMvt()) {
// MVT gridded data should not bootstrap each time the precision changes // MVT gridded data should not bootstrap each time the precision changes

View file

@ -20,12 +20,13 @@ import {
} from '../../../../common/constants'; } from '../../../../common/constants';
import { getField, addFieldToDSL } from '../../../../common/elasticsearch_util'; import { getField, addFieldToDSL } from '../../../../common/elasticsearch_util';
import { import {
DataFilters,
ESGeoLineSourceDescriptor, ESGeoLineSourceDescriptor,
ESGeoLineSourceResponseMeta, ESGeoLineSourceResponseMeta,
VectorSourceRequestMeta, VectorSourceRequestMeta,
} from '../../../../common/descriptor_types'; } from '../../../../common/descriptor_types';
import { getDataSourceLabel, getDataViewLabel } from '../../../../common/i18n_getters'; import { getDataSourceLabel, getDataViewLabel } from '../../../../common/i18n_getters';
import { AbstractESAggSource } from '../es_agg_source'; import { AbstractESAggSource, ESAggsSourceSyncMeta } from '../es_agg_source';
import { DataRequest } from '../../util/data_request'; import { DataRequest } from '../../util/data_request';
import { convertToGeoJson } from './convert_to_geojson'; import { convertToGeoJson } from './convert_to_geojson';
import { ESDocField } from '../../fields/es_doc_field'; import { ESDocField } from '../../fields/es_doc_field';
@ -39,7 +40,8 @@ import { getIsGoldPlus } from '../../../licensed_features';
import { LICENSED_FEATURES } from '../../../licensed_features'; import { LICENSED_FEATURES } from '../../../licensed_features';
import { mergeExecutionContext } from '../execution_context_utils'; import { mergeExecutionContext } from '../execution_context_utils';
type ESGeoLineSourceSyncMeta = Pick<ESGeoLineSourceDescriptor, 'splitField' | 'sortField'>; type ESGeoLineSourceSyncMeta = ESAggsSourceSyncMeta &
Pick<ESGeoLineSourceDescriptor, 'splitField' | 'sortField'>;
const MAX_TRACKS = 250; const MAX_TRACKS = 250;
@ -107,8 +109,9 @@ export class ESGeoLineSource extends AbstractESAggSource {
); );
} }
getSyncMeta(): ESGeoLineSourceSyncMeta { getSyncMeta(dataFilters: DataFilters): ESGeoLineSourceSyncMeta {
return { return {
...super.getSyncMeta(dataFilters),
splitField: this._descriptor.splitField, splitField: this._descriptor.splitField,
sortField: this._descriptor.sortField, sortField: this._descriptor.sortField,
}; };
@ -141,14 +144,6 @@ export class ESGeoLineSource extends AbstractESAggSource {
}); });
} }
getFieldNames() {
return [
...this.getMetricFields().map((esAggMetricField) => esAggMetricField.getName()),
this._descriptor.splitField,
this._descriptor.sortField,
];
}
async getFields(): Promise<IField[]> { async getFields(): Promise<IField[]> {
return [...this.getMetricFields(), this._createSplitField()]; return [...this.getMetricFields(), this._createSplitField()];
} }

View file

@ -93,6 +93,7 @@ export class ESPewPewSource extends AbstractESAggSource {
getSyncMeta(dataFilters: DataFilters) { getSyncMeta(dataFilters: DataFilters) {
return { return {
...super.getSyncMeta(dataFilters),
geogridPrecision: this.getGeoGridPrecision(dataFilters.zoom), geogridPrecision: this.getGeoGridPrecision(dataFilters.zoom),
}; };
} }

View file

@ -78,6 +78,7 @@ import { FeatureGeometryFilterForm } from '../../../connected_components/mb_map/
type ESSearchSourceSyncMeta = Pick< type ESSearchSourceSyncMeta = Pick<
ESSearchSourceDescriptor, ESSearchSourceDescriptor,
| 'geoField'
| 'filterByMapBounds' | 'filterByMapBounds'
| 'sortField' | 'sortField'
| 'sortOrder' | 'sortOrder'
@ -211,10 +212,6 @@ export class ESSearchSource extends AbstractESSource implements IMvtVectorSource
} }
} }
getFieldNames(): string[] {
return [this._descriptor.geoField];
}
isMvt() { isMvt() {
return this._descriptor.scalingType === SCALING_TYPES.MVT; return this._descriptor.scalingType === SCALING_TYPES.MVT;
} }
@ -282,12 +279,9 @@ export class ESSearchSource extends AbstractESSource implements IMvtVectorSource
const indexPattern: DataView = await this.getIndexPattern(); const indexPattern: DataView = await this.getIndexPattern();
const fieldNames = requestMeta.fieldNames.filter(
(fieldName) => fieldName !== this._descriptor.geoField
);
const { docValueFields, sourceOnlyFields, scriptFields } = getDocValueAndSourceFields( const { docValueFields, sourceOnlyFields, scriptFields } = getDocValueAndSourceFields(
indexPattern, indexPattern,
fieldNames, requestMeta.fieldNames,
'epoch_millis' 'epoch_millis'
); );
const topHits: { const topHits: {
@ -398,7 +392,6 @@ export class ESSearchSource extends AbstractESSource implements IMvtVectorSource
}; };
} }
// requestMeta.fieldNames contains geo field and any fields needed for styling features
// Performs Elasticsearch search request being careful to pull back only required fields to minimize response size // Performs Elasticsearch search request being careful to pull back only required fields to minimize response size
async _getSearchHits( async _getSearchHits(
layerName: string, layerName: string,
@ -408,12 +401,9 @@ export class ESSearchSource extends AbstractESSource implements IMvtVectorSource
) { ) {
const indexPattern = await this.getIndexPattern(); const indexPattern = await this.getIndexPattern();
const fieldNames = requestMeta.fieldNames.filter(
(fieldName) => fieldName !== this._descriptor.geoField
);
const { docValueFields, sourceOnlyFields } = getDocValueAndSourceFields( const { docValueFields, sourceOnlyFields } = getDocValueAndSourceFields(
indexPattern, indexPattern,
fieldNames, requestMeta.fieldNames,
'epoch_millis' 'epoch_millis'
); );
@ -537,6 +527,15 @@ export class ESSearchSource extends AbstractESSource implements IMvtVectorSource
return indexSettings.maxResultWindow; return indexSettings.maxResultWindow;
} }
/*
* Changes in requestMeta.fieldNames requires re-fetch.
* requestMeta.fieldNames are used to acheive smallest response possible.
* Response only includes fields required for client usage.
*/
isFieldAware(): boolean {
return true;
}
async getGeoJsonWithMeta( async getGeoJsonWithMeta(
layerName: string, layerName: string,
requestMeta: VectorSourceRequestMeta, requestMeta: VectorSourceRequestMeta,
@ -790,6 +789,7 @@ export class ESSearchSource extends AbstractESSource implements IMvtVectorSource
getSyncMeta(): ESSearchSourceSyncMeta { getSyncMeta(): ESSearchSourceSyncMeta {
return { return {
geoField: this._descriptor.geoField,
filterByMapBounds: this._descriptor.filterByMapBounds, filterByMapBounds: this._descriptor.filterByMapBounds,
sortField: this._descriptor.sortField, sortField: this._descriptor.sortField,
sortOrder: this._descriptor.sortOrder, sortOrder: this._descriptor.sortOrder,
@ -879,19 +879,15 @@ export class ESSearchSource extends AbstractESSource implements IMvtVectorSource
// use fields API // use fields API
searchSource.setField( searchSource.setField(
'fields', 'fields',
requestMeta.fieldNames requestMeta.fieldNames.map((fieldName) => {
.filter((fieldName) => { const field = dataView.fields.getByName(fieldName);
return fieldName !== this._descriptor.geoField; return field && field.type === 'date'
}) ? {
.map((fieldName) => { field: fieldName,
const field = dataView.fields.getByName(fieldName); format: 'epoch_millis',
return field && field.type === 'date' }
? { : fieldName;
field: fieldName, })
format: 'epoch_millis',
}
: fieldName;
})
); );
const mvtUrlServicePath = getHttp().basePath.prepend(`${MVT_GETTILE_API_PATH}/{z}/{x}/{y}.pbf`); const mvtUrlServicePath = getHttp().basePath.prepend(`${MVT_GETTILE_API_PATH}/{z}/{x}/{y}.pbf`);

View file

@ -129,10 +129,6 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource
return this._descriptor.applyForceRefresh; return this._descriptor.applyForceRefresh;
} }
isFieldAware(): boolean {
return true;
}
isQueryAware(): boolean { isQueryAware(): boolean {
return true; return true;
} }

View file

@ -15,13 +15,14 @@ import { getJoinAggKey } from '../../../../../common/get_agg_key';
import { AbstractESAggSource } from '../../es_agg_source'; import { AbstractESAggSource } from '../../es_agg_source';
import type { BucketProperties } from '../../../../../common/elasticsearch_util'; import type { BucketProperties } from '../../../../../common/elasticsearch_util';
import { import {
DataFilters,
ESDistanceSourceDescriptor, ESDistanceSourceDescriptor,
VectorSourceRequestMeta, VectorSourceRequestMeta,
} from '../../../../../common/descriptor_types'; } from '../../../../../common/descriptor_types';
import { PropertiesMap } from '../../../../../common/elasticsearch_util'; import { PropertiesMap } from '../../../../../common/elasticsearch_util';
import { isValidStringConfig } from '../../../util/valid_string_config'; import { isValidStringConfig } from '../../../util/valid_string_config';
import { IJoinSource } from '../types'; import { IJoinSource } from '../types';
import type { IESAggSource } from '../../es_agg_source'; import type { IESAggSource, ESAggsSourceSyncMeta } from '../../es_agg_source';
import { IField } from '../../../fields/field'; import { IField } from '../../../fields/field';
import { mergeExecutionContext } from '../../execution_context_utils'; import { mergeExecutionContext } from '../../execution_context_utils';
import { processDistanceResponse } from './process_distance_response'; import { processDistanceResponse } from './process_distance_response';
@ -29,7 +30,8 @@ import { isSpatialSourceComplete } from '../is_spatial_source_complete';
export const DEFAULT_WITHIN_DISTANCE = 5; export const DEFAULT_WITHIN_DISTANCE = 5;
type ESDistanceSourceSyncMeta = Pick<ESDistanceSourceDescriptor, 'distance' | 'geoField'>; type ESDistanceSourceSyncMeta = ESAggsSourceSyncMeta &
Pick<ESDistanceSourceDescriptor, 'distance' | 'geoField'>;
export class ESDistanceSource extends AbstractESAggSource implements IJoinSource, IESAggSource { export class ESDistanceSource extends AbstractESAggSource implements IJoinSource, IESAggSource {
static type = SOURCE_TYPES.ES_DISTANCE_SOURCE; static type = SOURCE_TYPES.ES_DISTANCE_SOURCE;
@ -162,12 +164,9 @@ export class ESDistanceSource extends AbstractESAggSource implements IJoinSource
return false; return false;
} }
getFieldNames(): string[] { getSyncMeta(dataFilters: DataFilters): ESDistanceSourceSyncMeta {
return this.getMetricFields().map((esAggMetricField) => esAggMetricField.getName());
}
getSyncMeta(): ESDistanceSourceSyncMeta {
return { return {
...super.getSyncMeta(dataFilters),
distance: this._descriptor.distance, distance: this._descriptor.distance,
geoField: this._descriptor.geoField, geoField: this._descriptor.geoField,
}; };

View file

@ -6,6 +6,7 @@
*/ */
import { AGG_TYPE } from '../../../../../common/constants'; import { AGG_TYPE } from '../../../../../common/constants';
import { DataFilters } from '../../../../../common/descriptor_types';
import type { BucketProperties, PropertiesMap } from '../../../../../common/elasticsearch_util'; import type { BucketProperties, PropertiesMap } from '../../../../../common/elasticsearch_util';
import { ESTermSource, extractPropertiesMap } from './es_term_source'; import { ESTermSource, extractPropertiesMap } from './es_term_source';
@ -117,8 +118,9 @@ describe('getSyncMeta', () => {
indexPatternId: 'foobar', indexPatternId: 'foobar',
size: 10, size: 10,
}); });
expect(source.getSyncMeta()).toEqual({ expect(source.getSyncMeta({} as unknown as DataFilters)).toEqual({
indexPatternId: 'foobar', indexPatternId: 'foobar',
metrics: ['__kbnjoin__count__1234'],
size: 10, size: 10,
term: 'myTermField', term: 'myTermField',
}); });

View file

@ -25,13 +25,14 @@ import {
BucketProperties, BucketProperties,
} from '../../../../../common/elasticsearch_util'; } from '../../../../../common/elasticsearch_util';
import { import {
DataFilters,
ESTermSourceDescriptor, ESTermSourceDescriptor,
VectorSourceRequestMeta, VectorSourceRequestMeta,
} from '../../../../../common/descriptor_types'; } from '../../../../../common/descriptor_types';
import { PropertiesMap } from '../../../../../common/elasticsearch_util'; import { PropertiesMap } from '../../../../../common/elasticsearch_util';
import { isValidStringConfig } from '../../../util/valid_string_config'; import { isValidStringConfig } from '../../../util/valid_string_config';
import { ITermJoinSource } from '../types'; import { ITermJoinSource } from '../types';
import type { IESAggSource } from '../../es_agg_source'; import type { IESAggSource, ESAggsSourceSyncMeta } from '../../es_agg_source';
import { IField } from '../../../fields/field'; import { IField } from '../../../fields/field';
import { mergeExecutionContext } from '../../execution_context_utils'; import { mergeExecutionContext } from '../../execution_context_utils';
import { isTermSourceComplete } from './is_term_source_complete'; import { isTermSourceComplete } from './is_term_source_complete';
@ -39,7 +40,8 @@ import { isTermSourceComplete } from './is_term_source_complete';
const TERMS_AGG_NAME = 'join'; const TERMS_AGG_NAME = 'join';
const TERMS_BUCKET_KEYS_TO_IGNORE = ['key', 'doc_count']; const TERMS_BUCKET_KEYS_TO_IGNORE = ['key', 'doc_count'];
type ESTermSourceSyncMeta = Pick<ESTermSourceDescriptor, 'indexPatternId' | 'size' | 'term'>; type ESTermSourceSyncMeta = ESAggsSourceSyncMeta &
Pick<ESTermSourceDescriptor, 'indexPatternId' | 'size' | 'term'>;
export function extractPropertiesMap(rawEsData: any, countPropertyName: string): PropertiesMap { export function extractPropertiesMap(rawEsData: any, countPropertyName: string): PropertiesMap {
const propertiesMap: PropertiesMap = new Map<string, BucketProperties>(); const propertiesMap: PropertiesMap = new Map<string, BucketProperties>();
@ -184,12 +186,9 @@ export class ESTermSource extends AbstractESAggSource implements ITermJoinSource
return `es_table ${this.getIndexPatternId()}`; return `es_table ${this.getIndexPatternId()}`;
} }
getFieldNames(): string[] { getSyncMeta(dataFilters: DataFilters): ESTermSourceSyncMeta {
return this.getMetricFields().map((esAggMetricField) => esAggMetricField.getName());
}
getSyncMeta(): ESTermSourceSyncMeta {
return { return {
...super.getSyncMeta(dataFilters),
indexPatternId: this._descriptor.indexPatternId, indexPatternId: this._descriptor.indexPatternId,
size: this._descriptor.size, size: this._descriptor.size,
term: this._descriptor.term, term: this._descriptor.term,

View file

@ -54,10 +54,6 @@ export class TableSource extends AbstractVectorSource implements ITermJoinSource
return `table source ${uuidv4()}`; return `table source ${uuidv4()}`;
} }
getSyncMeta(): null {
return null;
}
async getPropertiesMap( async getPropertiesMap(
requestMeta: VectorSourceRequestMeta, requestMeta: VectorSourceRequestMeta,
leftSourceName: string, leftSourceName: string,
@ -66,7 +62,9 @@ export class TableSource extends AbstractVectorSource implements ITermJoinSource
): Promise<PropertiesMap> { ): Promise<PropertiesMap> {
const propertiesMap: PropertiesMap = new Map<string, BucketProperties>(); const propertiesMap: PropertiesMap = new Map<string, BucketProperties>();
const fieldNames = await this.getFieldNames(); const columnNames = this._descriptor.__columns.map((column) => {
return column.name;
});
for (let i = 0; i < this._descriptor.__rows.length; i++) { for (let i = 0; i < this._descriptor.__rows.length; i++) {
const row: { [key: string]: string | number } = this._descriptor.__rows[i]; const row: { [key: string]: string | number } = this._descriptor.__rows[i];
@ -77,7 +75,7 @@ export class TableSource extends AbstractVectorSource implements ITermJoinSource
if (key === this._descriptor.term && row[key]) { if (key === this._descriptor.term && row[key]) {
propKey = row[key]; propKey = row[key];
} }
if (fieldNames.indexOf(key) >= 0 && key !== this._descriptor.term) { if (columnNames.indexOf(key) >= 0 && key !== this._descriptor.term) {
props[key] = row[key]; props[key] = row[key];
} }
} }
@ -137,12 +135,6 @@ export class TableSource extends AbstractVectorSource implements ITermJoinSource
}); });
} }
getFieldNames(): string[] {
return this._descriptor.__columns.map((column) => {
return column.name;
});
}
hasTooltipProperties(): boolean { hasTooltipProperties(): boolean {
return false; return false;
} }

View file

@ -10,7 +10,7 @@ import type { KibanaExecutionContext } from '@kbn/core/public';
import { Query } from '@kbn/data-plugin/common/query'; import { Query } from '@kbn/data-plugin/common/query';
import { Adapters } from '@kbn/inspector-plugin/common/adapters'; import { Adapters } from '@kbn/inspector-plugin/common/adapters';
import { IField } from '../../fields/field'; import { IField } from '../../fields/field';
import { VectorSourceRequestMeta } from '../../../../common/descriptor_types'; import { DataFilters, VectorSourceRequestMeta } from '../../../../common/descriptor_types';
import { PropertiesMap } from '../../../../common/elasticsearch_util'; import { PropertiesMap } from '../../../../common/elasticsearch_util';
import { ITooltipProperty } from '../../tooltips/tooltip_property'; import { ITooltipProperty } from '../../tooltips/tooltip_property';
import { ISource } from '../source'; import { ISource } from '../source';
@ -28,10 +28,9 @@ export interface IJoinSource extends ISource {
): Promise<PropertiesMap>; ): Promise<PropertiesMap>;
/* /*
* Vector layer avoids unnecessarily re-fetching join data. * Use getSyncMeta to expose join configurations that require join data re-fetch when changed.
* Use getSyncMeta to expose fields that require join data re-fetch when changed.
*/ */
getSyncMeta(): object | null; getSyncMeta(dataFilters: DataFilters): object | null;
getId(): string; getId(): string;
getRightFields(): IField[]; getRightFields(): IField[];

View file

@ -92,12 +92,6 @@ export class MVTSingleLayerVectorSource extends AbstractSource implements IMvtVe
); );
} }
getFieldNames(): string[] {
return this._descriptor.fields.map((field: MVTFieldDescriptor) => {
return field.name;
});
}
addFeature(geometry: Geometry | Position[]): Promise<void> { addFeature(geometry: Geometry | Position[]): Promise<void> {
throw new Error('Does not implement addFeature'); throw new Error('Does not implement addFeature');
} }
@ -191,8 +185,12 @@ export class MVTSingleLayerVectorSource extends AbstractSource implements IMvtVe
return null; return null;
} }
getSyncMeta(): null { getSyncMeta() {
return null; return {
mvtFields: this._descriptor.fields.map((field: MVTFieldDescriptor) => {
return field.name;
}),
};
} }
isBoundsAware() { isBoundsAware() {

View file

@ -46,6 +46,13 @@ export type ImmutableSourceProperty = {
export interface ISource { export interface ISource {
getDisplayName(): Promise<string>; getDisplayName(): Promise<string>;
getType(): string; getType(): string;
/*
* Re-fetch flag. When function returns true, source will re-fetch on requestMeta.fieldNames changes.
* Example uses of fieldNames change requiring re-fetch:
* 1) Data driven styling
* 2) Term join
* 3) Feature masking.
*/
isFieldAware(): boolean; isFieldAware(): boolean;
isFilterByMapBounds(): boolean; isFilterByMapBounds(): boolean;
isQueryAware(): boolean; isQueryAware(): boolean;
@ -56,7 +63,6 @@ export interface ISource {
renderSourceSettingsEditor(sourceEditorArgs: SourceEditorArgs): ReactElement<any> | null; renderSourceSettingsEditor(sourceEditorArgs: SourceEditorArgs): ReactElement<any> | null;
supportsFitToBounds(): Promise<boolean>; supportsFitToBounds(): Promise<boolean>;
cloneDescriptor(): AbstractSourceDescriptor; cloneDescriptor(): AbstractSourceDescriptor;
getFieldNames(): string[];
getApplyGlobalQuery(): boolean; getApplyGlobalQuery(): boolean;
getApplyGlobalTime(): boolean; getApplyGlobalTime(): boolean;
getApplyForceRefresh(): boolean; getApplyForceRefresh(): boolean;
@ -113,10 +119,6 @@ export class AbstractSource implements ISource {
return false; return false;
} }
getFieldNames(): string[] {
return [];
}
renderSourceSettingsEditor(sourceEditorArgs: SourceEditorArgs): ReactElement<any> | null { renderSourceSettingsEditor(sourceEditorArgs: SourceEditorArgs): ReactElement<any> | null {
return null; return null;
} }

View file

@ -109,12 +109,10 @@ export interface IVectorSource extends ISource {
supportsJoins(): boolean; supportsJoins(): boolean;
/* /*
* Vector layer avoids unnecessarily re-fetching source data. * Use getSyncMeta to expose source configuration changes that require source data re-fetch when changed.
* Use getSyncMeta to expose fields that require source data re-fetch when changed.
*/ */
getSyncMeta(dataFilters: DataFilters): object | null; getSyncMeta(dataFilters: DataFilters): object | null;
getFieldNames(): string[];
createField({ fieldName }: { fieldName: string }): IField; createField({ fieldName }: { fieldName: string }): IField;
hasTooltipProperties(): boolean; hasTooltipProperties(): boolean;
getSupportedShapeTypes(): Promise<VECTOR_SHAPE_TYPE[]>; getSupportedShapeTypes(): Promise<VECTOR_SHAPE_TYPE[]>;
@ -141,10 +139,6 @@ export interface IVectorSource extends ISource {
} }
export class AbstractVectorSource extends AbstractSource implements IVectorSource { export class AbstractVectorSource extends AbstractSource implements IVectorSource {
getFieldNames(): string[] {
return [];
}
isMvt() { isMvt() {
return false; return false;
} }

View file

@ -185,12 +185,10 @@ export class AnomalySource implements IVectorSource {
return false; return false;
} }
getFieldNames(): string[] {
return Object.keys(ANOMALY_SOURCE_FIELDS);
}
async getFields(): Promise<IField[]> { async getFields(): Promise<IField[]> {
return this.getFieldNames().map((field) => new AnomalySourceField({ source: this, field })); return Object.keys(ANOMALY_SOURCE_FIELDS).map(
(field) => new AnomalySourceField({ source: this, field })
);
} }
getGeoGridPrecision(zoom: number): number { getGeoGridPrecision(zoom: number): number {