mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Maps] do not track total hits for elasticsearch search requests (#91754)
* [Maps] do not track total hits for elasticsearch search requests * set track_total_hits for es_search_source tooltip fetch * tslint * searchSource doc updates, set track_total_hits in MVT requests * revert changes made to searchsourcefields docs * tslint * review feedback * tslint * remove Hits (Total) from functional tests * remove sleep in functional test * tslint * fix method name Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
6b6404954e
commit
c5e3e78de8
18 changed files with 198 additions and 137 deletions
|
@ -8,3 +8,4 @@
|
|||
export * from './es_agg_utils';
|
||||
export * from './convert_to_geojson';
|
||||
export * from './elasticsearch_geo_utils';
|
||||
export { isTotalHitsGreaterThan, TotalHits } from './total_hits';
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { isTotalHitsGreaterThan, TotalHits } from './total_hits';
|
||||
|
||||
describe('total.relation: eq', () => {
|
||||
const totalHits = {
|
||||
value: 100,
|
||||
relation: 'eq' as TotalHits['relation'],
|
||||
};
|
||||
|
||||
test('total.value: 100 should be more than 90', () => {
|
||||
expect(isTotalHitsGreaterThan(totalHits, 90)).toBe(true);
|
||||
});
|
||||
|
||||
test('total.value: 100 should not be more than 100', () => {
|
||||
expect(isTotalHitsGreaterThan(totalHits, 100)).toBe(false);
|
||||
});
|
||||
|
||||
test('total.value: 100 should not be more than 110', () => {
|
||||
expect(isTotalHitsGreaterThan(totalHits, 110)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('total.relation: gte', () => {
|
||||
const totalHits = {
|
||||
value: 100,
|
||||
relation: 'gte' as TotalHits['relation'],
|
||||
};
|
||||
|
||||
test('total.value: 100 should be more than 90', () => {
|
||||
expect(isTotalHitsGreaterThan(totalHits, 90)).toBe(true);
|
||||
});
|
||||
|
||||
test('total.value: 100 should be more than 100', () => {
|
||||
expect(isTotalHitsGreaterThan(totalHits, 100)).toBe(true);
|
||||
});
|
||||
|
||||
test('total.value: 100 should throw error when value is more than 100', () => {
|
||||
expect(() => {
|
||||
isTotalHitsGreaterThan(totalHits, 110);
|
||||
}).toThrow();
|
||||
});
|
||||
});
|
33
x-pack/plugins/maps/common/elasticsearch_util/total_hits.ts
Normal file
33
x-pack/plugins/maps/common/elasticsearch_util/total_hits.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export interface TotalHits {
|
||||
value: number;
|
||||
relation: 'eq' | 'gte';
|
||||
}
|
||||
|
||||
export function isTotalHitsGreaterThan(totalHits: TotalHits, value: number) {
|
||||
if (totalHits.relation === 'eq') {
|
||||
return totalHits.value > value;
|
||||
}
|
||||
|
||||
if (value > totalHits.value) {
|
||||
throw new Error(
|
||||
i18n.translate('xpack.maps.totalHits.lowerBoundPrecisionExceeded', {
|
||||
defaultMessage: `Unable to determine if total hits is greater than value. Total hits precision is lower then value. Total hits: {totalHitsString}, value: {value}. Ensure _search.body.track_total_hits is at least as large as value.`,
|
||||
values: {
|
||||
totalHitsString: JSON.stringify(totalHits, null, ''),
|
||||
value,
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -22,6 +22,7 @@ import {
|
|||
LAYER_STYLE_TYPE,
|
||||
FIELD_ORIGIN,
|
||||
} from '../../../../common/constants';
|
||||
import { isTotalHitsGreaterThan, TotalHits } from '../../../../common/elasticsearch_util';
|
||||
import { ESGeoGridSource } from '../../sources/es_geo_grid_source/es_geo_grid_source';
|
||||
import { canSkipSourceUpdate } from '../../util/can_skip_fetch';
|
||||
import { IESSource } from '../../sources/es_source';
|
||||
|
@ -323,13 +324,18 @@ export class BlendedVectorLayer extends VectorLayer implements IVectorLayer {
|
|||
syncContext.startLoading(dataRequestId, requestToken, searchFilters);
|
||||
const abortController = new AbortController();
|
||||
syncContext.registerCancelCallback(requestToken, () => abortController.abort());
|
||||
const maxResultWindow = await this._documentSource.getMaxResultWindow();
|
||||
const searchSource = await this._documentSource.makeSearchSource(searchFilters, 0);
|
||||
searchSource.setField('trackTotalHits', maxResultWindow + 1);
|
||||
const resp = await searchSource.fetch({
|
||||
abortSignal: abortController.signal,
|
||||
sessionId: syncContext.dataFilters.searchSessionId,
|
||||
legacyHitsTotal: false,
|
||||
});
|
||||
const maxResultWindow = await this._documentSource.getMaxResultWindow();
|
||||
isSyncClustered = resp.hits.total > maxResultWindow;
|
||||
isSyncClustered = isTotalHitsGreaterThan(
|
||||
(resp.hits.total as unknown) as TotalHits,
|
||||
maxResultWindow
|
||||
);
|
||||
const countData = { isSyncClustered } as CountData;
|
||||
syncContext.stopLoading(dataRequestId, requestToken, countData, searchFilters);
|
||||
} catch (error) {
|
||||
|
|
|
@ -368,6 +368,7 @@ export class ESGeoGridSource extends AbstractESAggSource implements ITiledSingle
|
|||
): Promise<GeoJsonWithMeta> {
|
||||
const indexPattern: IndexPattern = await this.getIndexPattern();
|
||||
const searchSource: ISearchSource = await this.makeSearchSource(searchFilters, 0);
|
||||
searchSource.setField('trackTotalHits', false);
|
||||
|
||||
let bucketsPerGrid = 1;
|
||||
this.getMetricFields().forEach((metricField) => {
|
||||
|
|
|
@ -190,6 +190,7 @@ export class ESGeoLineSource extends AbstractESAggSource {
|
|||
// Fetch entities
|
||||
//
|
||||
const entitySearchSource = await this.makeSearchSource(searchFilters, 0);
|
||||
entitySearchSource.setField('trackTotalHits', false);
|
||||
const splitField = getField(indexPattern, this._descriptor.splitField);
|
||||
const cardinalityAgg = { precision_threshold: 1 };
|
||||
const termsAgg = { size: MAX_TRACKS };
|
||||
|
@ -250,6 +251,7 @@ export class ESGeoLineSource extends AbstractESAggSource {
|
|||
const tracksSearchFilters = { ...searchFilters };
|
||||
delete tracksSearchFilters.buffer;
|
||||
const tracksSearchSource = await this.makeSearchSource(tracksSearchFilters, 0);
|
||||
tracksSearchSource.setField('trackTotalHits', false);
|
||||
tracksSearchSource.setField('aggs', {
|
||||
tracks: {
|
||||
filters: {
|
||||
|
|
|
@ -109,6 +109,7 @@ export class ESPewPewSource extends AbstractESAggSource {
|
|||
async getGeoJsonWithMeta(layerName, searchFilters, registerCancelCallback) {
|
||||
const indexPattern = await this.getIndexPattern();
|
||||
const searchSource = await this.makeSearchSource(searchFilters, 0);
|
||||
searchSource.setField('trackTotalHits', false);
|
||||
searchSource.setField('aggs', {
|
||||
destSplit: {
|
||||
terms: {
|
||||
|
@ -168,6 +169,7 @@ export class ESPewPewSource extends AbstractESAggSource {
|
|||
|
||||
async getBoundsForFilters(boundsFilters, registerCancelCallback) {
|
||||
const searchSource = await this.makeSearchSource(boundsFilters, 0);
|
||||
searchSource.setField('trackTotalHits', false);
|
||||
searchSource.setField('aggs', {
|
||||
destFitToBounds: {
|
||||
geo_bounds: {
|
||||
|
@ -185,7 +187,10 @@ export class ESPewPewSource extends AbstractESAggSource {
|
|||
try {
|
||||
const abortController = new AbortController();
|
||||
registerCancelCallback(() => abortController.abort());
|
||||
const esResp = await searchSource.fetch({ abortSignal: abortController.signal });
|
||||
const esResp = await searchSource.fetch({
|
||||
abortSignal: abortController.signal,
|
||||
legacyHitsTotal: false,
|
||||
});
|
||||
if (esResp.aggregations.destFitToBounds.bounds) {
|
||||
corners.push([
|
||||
esResp.aggregations.destFitToBounds.bounds.top_left.lon,
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
addFieldToDSL,
|
||||
getField,
|
||||
hitsToGeoJson,
|
||||
isTotalHitsGreaterThan,
|
||||
PreIndexedShape,
|
||||
} from '../../../../common/elasticsearch_util';
|
||||
// @ts-expect-error
|
||||
|
@ -313,6 +314,7 @@ export class ESSearchSource extends AbstractESSource implements ITiledSingleLaye
|
|||
};
|
||||
|
||||
const searchSource = await this.makeSearchSource(searchFilters, 0);
|
||||
searchSource.setField('trackTotalHits', false);
|
||||
searchSource.setField('aggs', {
|
||||
totalEntities: {
|
||||
cardinality: addFieldToDSL(cardinalityAgg, topHitsSplitField),
|
||||
|
@ -343,11 +345,10 @@ export class ESSearchSource extends AbstractESSource implements ITiledSingleLaye
|
|||
const areEntitiesTrimmed = entityBuckets.length >= DEFAULT_MAX_BUCKETS_LIMIT;
|
||||
let areTopHitsTrimmed = false;
|
||||
entityBuckets.forEach((entityBucket: any) => {
|
||||
const total = _.get(entityBucket, 'entityHits.hits.total', 0);
|
||||
const hits = _.get(entityBucket, 'entityHits.hits.hits', []);
|
||||
// Reverse hits list so top documents by sort are drawn on top
|
||||
allHits.push(...hits.reverse());
|
||||
if (total > hits.length) {
|
||||
if (isTotalHitsGreaterThan(entityBucket.entityHits.hits.total, hits.length)) {
|
||||
areTopHitsTrimmed = true;
|
||||
}
|
||||
});
|
||||
|
@ -385,6 +386,7 @@ export class ESSearchSource extends AbstractESSource implements ITiledSingleLaye
|
|||
maxResultWindow,
|
||||
initialSearchContext
|
||||
);
|
||||
searchSource.setField('trackTotalHits', maxResultWindow + 1);
|
||||
searchSource.setField('fieldsFromSource', searchFilters.fieldNames); // Setting "fields" filters out unused scripted fields
|
||||
if (sourceOnlyFields.length === 0) {
|
||||
searchSource.setField('source', false); // do not need anything from _source
|
||||
|
@ -408,7 +410,7 @@ export class ESSearchSource extends AbstractESSource implements ITiledSingleLaye
|
|||
hits: resp.hits.hits.reverse(), // Reverse hits so top documents by sort are drawn on top
|
||||
meta: {
|
||||
resultsCount: resp.hits.hits.length,
|
||||
areResultsTrimmed: resp.hits.total > resp.hits.hits.length,
|
||||
areResultsTrimmed: isTotalHitsGreaterThan(resp.hits.total, resp.hits.hits.length),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -508,6 +510,7 @@ export class ESSearchSource extends AbstractESSource implements ITiledSingleLaye
|
|||
const initialSearchContext = { docvalue_fields: docValueFields }; // Request fields in docvalue_fields insted of _source
|
||||
const searchService = getSearchService();
|
||||
const searchSource = await searchService.searchSource.create(initialSearchContext as object);
|
||||
searchSource.setField('trackTotalHits', false);
|
||||
|
||||
searchSource.setField('index', indexPattern);
|
||||
searchSource.setField('size', 1);
|
||||
|
@ -520,7 +523,7 @@ export class ESSearchSource extends AbstractESSource implements ITiledSingleLaye
|
|||
searchSource.setField('query', query);
|
||||
searchSource.setField('fieldsFromSource', this._getTooltipPropertyNames());
|
||||
|
||||
const resp = await searchSource.fetch();
|
||||
const resp = await searchSource.fetch({ legacyHitsTotal: false });
|
||||
|
||||
const hit = _.get(resp, 'hits.hits[0]');
|
||||
if (!hit) {
|
||||
|
|
|
@ -195,6 +195,7 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource
|
|||
resp = await searchSource.fetch({
|
||||
abortSignal: abortController.signal,
|
||||
sessionId: searchSessionId,
|
||||
legacyHitsTotal: false,
|
||||
});
|
||||
if (inspectorRequest) {
|
||||
const responseStats = search.getResponseInspectorStats(resp, searchSource);
|
||||
|
@ -247,6 +248,7 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource
|
|||
}
|
||||
}
|
||||
const searchService = getSearchService();
|
||||
|
||||
const searchSource = await searchService.searchSource.create(initialSearchContext);
|
||||
|
||||
searchSource.setField('index', indexPattern);
|
||||
|
@ -272,6 +274,7 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource
|
|||
registerCancelCallback: (callback: () => void) => void
|
||||
): Promise<MapExtent | null> {
|
||||
const searchSource = await this.makeSearchSource(boundsFilters, 0);
|
||||
searchSource.setField('trackTotalHits', false);
|
||||
searchSource.setField('aggs', {
|
||||
fitToBounds: {
|
||||
geo_bounds: {
|
||||
|
@ -284,7 +287,10 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource
|
|||
try {
|
||||
const abortController = new AbortController();
|
||||
registerCancelCallback(() => abortController.abort());
|
||||
const esResp = await searchSource.fetch({ abortSignal: abortController.signal });
|
||||
const esResp = await searchSource.fetch({
|
||||
abortSignal: abortController.signal,
|
||||
legacyHitsTotal: false,
|
||||
});
|
||||
|
||||
if (!esResp.aggregations) {
|
||||
return null;
|
||||
|
|
|
@ -127,6 +127,7 @@ export class ESTermSource extends AbstractESAggSource implements ITermJoinSource
|
|||
|
||||
const indexPattern = await this.getIndexPattern();
|
||||
const searchSource: ISearchSource = await this.makeSearchSource(searchFilters, 0);
|
||||
searchSource.setField('trackTotalHits', false);
|
||||
const termsField = getField(indexPattern, this._termField.getName());
|
||||
const termsAgg = {
|
||||
size: this._descriptor.size !== undefined ? this._descriptor.size : DEFAULT_MAX_BUCKETS_LIMIT,
|
||||
|
|
|
@ -23,7 +23,12 @@ import {
|
|||
SUPER_FINE_ZOOM_DELTA,
|
||||
} from '../../common/constants';
|
||||
|
||||
import { convertRegularRespToGeoJson, hitsToGeoJson } from '../../common/elasticsearch_util';
|
||||
import {
|
||||
convertRegularRespToGeoJson,
|
||||
hitsToGeoJson,
|
||||
isTotalHitsGreaterThan,
|
||||
TotalHits,
|
||||
} from '../../common/elasticsearch_util';
|
||||
import { flattenHit } from './util';
|
||||
import { ESBounds, tileToESBbox } from '../../common/geo_tile_utils';
|
||||
import { getCentroidFeatures } from '../../common/get_centroid_features';
|
||||
|
@ -67,6 +72,7 @@ export async function getGridTile({
|
|||
MAX_ZOOM
|
||||
);
|
||||
requestBody.aggs[GEOTILE_GRID_AGG_NAME].geotile_grid.bounds = tileBounds;
|
||||
requestBody.track_total_hits = false;
|
||||
|
||||
const response = await context
|
||||
.search!.search(
|
||||
|
@ -78,6 +84,7 @@ export async function getGridTile({
|
|||
},
|
||||
{
|
||||
sessionId: searchSessionId,
|
||||
legacyHitsTotal: false,
|
||||
abortSignal,
|
||||
}
|
||||
)
|
||||
|
@ -130,6 +137,7 @@ export async function getTile({
|
|||
|
||||
const searchOptions = {
|
||||
sessionId: searchSessionId,
|
||||
legacyHitsTotal: false,
|
||||
abortSignal,
|
||||
};
|
||||
|
||||
|
@ -141,6 +149,7 @@ export async function getTile({
|
|||
body: {
|
||||
size: 0,
|
||||
query: requestBody.query,
|
||||
track_total_hits: requestBody.size + 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -148,7 +157,12 @@ export async function getTile({
|
|||
)
|
||||
.toPromise();
|
||||
|
||||
if (countResponse.rawResponse.hits.total > requestBody.size) {
|
||||
if (
|
||||
isTotalHitsGreaterThan(
|
||||
(countResponse.rawResponse.hits.total as unknown) as TotalHits,
|
||||
requestBody.size
|
||||
)
|
||||
) {
|
||||
// Generate "too many features"-bounds
|
||||
const bboxResponse = await context
|
||||
.search!.search(
|
||||
|
@ -165,6 +179,7 @@ export async function getTile({
|
|||
},
|
||||
},
|
||||
},
|
||||
track_total_hits: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -191,7 +206,10 @@ export async function getTile({
|
|||
{
|
||||
params: {
|
||||
index,
|
||||
body: requestBody,
|
||||
body: {
|
||||
...requestBody,
|
||||
track_total_hits: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
searchOptions
|
||||
|
|
|
@ -27,28 +27,21 @@ export default function ({ getPageObjects, getService }) {
|
|||
});
|
||||
|
||||
it('should request documents when zoomed to smaller regions showing less data', async () => {
|
||||
const hits = await PageObjects.maps.getHits();
|
||||
const response = await PageObjects.maps.getResponse();
|
||||
// Allow a range of hits to account for variances in browser window size.
|
||||
expect(parseInt(hits)).to.be.within(30, 40);
|
||||
expect(response.hits.hits.length).to.be.within(30, 40);
|
||||
});
|
||||
|
||||
it('should request clusters when zoomed to larger regions showing lots of data', async () => {
|
||||
await PageObjects.maps.setView(20, -90, 2);
|
||||
await inspector.open();
|
||||
await inspector.openInspectorRequestsView();
|
||||
const requestStats = await inspector.getTableData();
|
||||
const hits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits');
|
||||
const totalHits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits (total)');
|
||||
await inspector.close();
|
||||
|
||||
expect(hits).to.equal('0');
|
||||
expect(totalHits).to.equal('14000');
|
||||
const response = await PageObjects.maps.getResponse();
|
||||
expect(response.aggregations.gridSplit.buckets.length).to.equal(17);
|
||||
});
|
||||
|
||||
it('should request documents when query narrows data', async () => {
|
||||
await PageObjects.maps.setAndSubmitQuery('bytes > 19000');
|
||||
const hits = await PageObjects.maps.getHits();
|
||||
expect(hits).to.equal('75');
|
||||
const response = await PageObjects.maps.getResponse();
|
||||
expect(response.hits.hits.length).to.equal(75);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -9,9 +9,6 @@ import expect from '@kbn/expect';
|
|||
|
||||
export default function ({ getPageObjects, getService }) {
|
||||
const PageObjects = getPageObjects(['maps']);
|
||||
const inspector = getService('inspector');
|
||||
const monacoEditor = getService('monacoEditor');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const security = getService('security');
|
||||
|
||||
describe('docvalue_fields', () => {
|
||||
|
@ -24,18 +21,9 @@ export default function ({ getPageObjects, getService }) {
|
|||
await security.testUser.restoreDefaults();
|
||||
});
|
||||
|
||||
async function getResponse() {
|
||||
await inspector.open();
|
||||
await inspector.openInspectorRequestsView();
|
||||
await testSubjects.click('inspectorRequestDetailResponse');
|
||||
const responseBody = await monacoEditor.getCodeEditorValue();
|
||||
await inspector.close();
|
||||
return JSON.parse(responseBody);
|
||||
}
|
||||
|
||||
it('should only fetch geo_point field and nothing else when source does not have data driven styling', async () => {
|
||||
await PageObjects.maps.loadSavedMap('document example');
|
||||
const response = await getResponse();
|
||||
const response = await PageObjects.maps.getResponse();
|
||||
const firstHit = response.hits.hits[0];
|
||||
expect(firstHit).to.only.have.keys(['_id', '_index', '_score', 'fields']);
|
||||
expect(firstHit.fields).to.only.have.keys(['geo.coordinates']);
|
||||
|
@ -43,7 +31,7 @@ export default function ({ getPageObjects, getService }) {
|
|||
|
||||
it('should only fetch geo_point field and data driven styling fields', async () => {
|
||||
await PageObjects.maps.loadSavedMap('document example with data driven styles');
|
||||
const response = await getResponse();
|
||||
const response = await PageObjects.maps.getResponse();
|
||||
const firstHit = response.hits.hits[0];
|
||||
expect(firstHit).to.only.have.keys(['_id', '_index', '_score', 'fields']);
|
||||
expect(firstHit.fields).to.only.have.keys(['bytes', 'geo.coordinates', 'hour_of_day']);
|
||||
|
@ -51,7 +39,7 @@ export default function ({ getPageObjects, getService }) {
|
|||
|
||||
it('should format date fields as epoch_millis when data driven styling is applied to a date field', async () => {
|
||||
await PageObjects.maps.loadSavedMap('document example with data driven styles on date field');
|
||||
const response = await getResponse();
|
||||
const response = await PageObjects.maps.getResponse();
|
||||
const firstHit = response.hits.hits[0];
|
||||
expect(firstHit).to.only.have.keys(['_id', '_index', '_score', 'fields']);
|
||||
expect(firstHit.fields).to.only.have.keys(['@timestamp', 'bytes', 'geo.coordinates']);
|
||||
|
|
|
@ -14,7 +14,6 @@ export default function ({ getPageObjects, getService }) {
|
|||
const filterBar = getService('filterBar');
|
||||
const dashboardPanelActions = getService('dashboardPanelActions');
|
||||
const inspector = getService('inspector');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const browser = getService('browser');
|
||||
const retry = getService('retry');
|
||||
const security = getService('security');
|
||||
|
@ -81,11 +80,10 @@ export default function ({ getPageObjects, getService }) {
|
|||
});
|
||||
|
||||
it('should apply container state (time, query, filters) to embeddable when loaded', async () => {
|
||||
await dashboardPanelActions.openInspectorByTitle('geo grid vector grid example');
|
||||
const requestStats = await inspector.getTableData();
|
||||
const totalHits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits (total)');
|
||||
await inspector.close();
|
||||
expect(totalHits).to.equal('6');
|
||||
const response = await PageObjects.maps.getResponseFromDashboardPanel(
|
||||
'geo grid vector grid example'
|
||||
);
|
||||
expect(response.aggregations.gridSplit.buckets.length).to.equal(6);
|
||||
});
|
||||
|
||||
it('should apply new container state (time, query, filters) to embeddable', async () => {
|
||||
|
@ -94,25 +92,16 @@ export default function ({ getPageObjects, getService }) {
|
|||
await filterBar.selectIndexPattern('meta_for_geo_shapes*');
|
||||
await filterBar.addFilter('shape_name', 'is', 'alpha');
|
||||
|
||||
await dashboardPanelActions.openInspectorByTitle('geo grid vector grid example');
|
||||
const geoGridRequestStats = await inspector.getTableData();
|
||||
const geoGridTotalHits = PageObjects.maps.getInspectorStatRowHit(
|
||||
geoGridRequestStats,
|
||||
'Hits (total)'
|
||||
const gridResponse = await PageObjects.maps.getResponseFromDashboardPanel(
|
||||
'geo grid vector grid example'
|
||||
);
|
||||
await inspector.close();
|
||||
expect(geoGridTotalHits).to.equal('1');
|
||||
expect(gridResponse.aggregations.gridSplit.buckets.length).to.equal(1);
|
||||
|
||||
await dashboardPanelActions.openInspectorByTitle('join example');
|
||||
await testSubjects.click('inspectorRequestChooser');
|
||||
await testSubjects.click('inspectorRequestChoosermeta_for_geo_shapes*.shape_name');
|
||||
const joinRequestStats = await inspector.getTableData();
|
||||
const joinTotalHits = PageObjects.maps.getInspectorStatRowHit(
|
||||
joinRequestStats,
|
||||
'Hits (total)'
|
||||
const joinResponse = await PageObjects.maps.getResponseFromDashboardPanel(
|
||||
'join example',
|
||||
'meta_for_geo_shapes*.shape_name'
|
||||
);
|
||||
await inspector.close();
|
||||
expect(joinTotalHits).to.equal('3');
|
||||
expect(joinResponse.aggregations.join.buckets.length).to.equal(1);
|
||||
});
|
||||
|
||||
it('should re-fetch query when "refresh" is clicked', async () => {
|
||||
|
|
|
@ -141,12 +141,8 @@ export default function ({ getPageObjects, getService }) {
|
|||
});
|
||||
|
||||
it('should apply query to geotile_grid aggregation request', async () => {
|
||||
await inspector.open();
|
||||
await inspector.openInspectorRequestsView();
|
||||
const requestStats = await inspector.getTableData();
|
||||
const hits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits (total)');
|
||||
await inspector.close();
|
||||
expect(hits).to.equal('1');
|
||||
const response = await PageObjects.maps.getResponse();
|
||||
expect(response.aggregations.gridSplit.buckets.length).to.equal(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -156,18 +152,8 @@ export default function ({ getPageObjects, getService }) {
|
|||
});
|
||||
|
||||
it('should contain geotile_grid aggregation elasticsearch request', async () => {
|
||||
await inspector.open();
|
||||
await inspector.openInspectorRequestsView();
|
||||
const requestStats = await inspector.getTableData();
|
||||
const totalHits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits (total)');
|
||||
expect(totalHits).to.equal('6');
|
||||
const hits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits');
|
||||
expect(hits).to.equal('0'); // aggregation requests do not return any documents
|
||||
const indexPatternName = PageObjects.maps.getInspectorStatRowHit(
|
||||
requestStats,
|
||||
'Index pattern'
|
||||
);
|
||||
expect(indexPatternName).to.equal('logstash-*');
|
||||
const response = await PageObjects.maps.getResponse();
|
||||
expect(response.aggregations.gridSplit.buckets.length).to.equal(4);
|
||||
});
|
||||
|
||||
it('should not contain any elasticsearch request after layer is deleted', async () => {
|
||||
|
@ -218,12 +204,8 @@ export default function ({ getPageObjects, getService }) {
|
|||
});
|
||||
|
||||
it('should apply query to geotile_grid aggregation request', async () => {
|
||||
await inspector.open();
|
||||
await inspector.openInspectorRequestsView();
|
||||
const requestStats = await inspector.getTableData();
|
||||
const hits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits (total)');
|
||||
await inspector.close();
|
||||
expect(hits).to.equal('1');
|
||||
const response = await PageObjects.maps.getResponse();
|
||||
expect(response.aggregations.gridSplit.buckets.length).to.equal(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -233,18 +215,8 @@ export default function ({ getPageObjects, getService }) {
|
|||
});
|
||||
|
||||
it('should contain geotile_grid aggregation elasticsearch request', async () => {
|
||||
await inspector.open();
|
||||
await inspector.openInspectorRequestsView();
|
||||
const requestStats = await inspector.getTableData();
|
||||
const totalHits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits (total)');
|
||||
expect(totalHits).to.equal('6');
|
||||
const hits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits');
|
||||
expect(hits).to.equal('0'); // aggregation requests do not return any documents
|
||||
const indexPatternName = PageObjects.maps.getInspectorStatRowHit(
|
||||
requestStats,
|
||||
'Index pattern'
|
||||
);
|
||||
expect(indexPatternName).to.equal('logstash-*');
|
||||
const response = await PageObjects.maps.getResponse();
|
||||
expect(response.aggregations.gridSplit.buckets.length).to.equal(4);
|
||||
});
|
||||
|
||||
it('should not contain any elasticsearch request after layer is deleted', async () => {
|
||||
|
@ -272,18 +244,8 @@ export default function ({ getPageObjects, getService }) {
|
|||
});
|
||||
|
||||
it('should contain geotile_grid aggregation elasticsearch request', async () => {
|
||||
await inspector.open();
|
||||
await inspector.openInspectorRequestsView();
|
||||
const requestStats = await inspector.getTableData();
|
||||
const totalHits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits (total)');
|
||||
expect(totalHits).to.equal('4'); //4 geometries result in 13 cells due to way they overlap geotile_grid cells
|
||||
const hits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits');
|
||||
expect(hits).to.equal('0'); // aggregation requests do not return any documents
|
||||
const indexPatternName = PageObjects.maps.getInspectorStatRowHit(
|
||||
requestStats,
|
||||
'Index pattern'
|
||||
);
|
||||
expect(indexPatternName).to.equal('geo_shapes*');
|
||||
const response = await PageObjects.maps.getResponse();
|
||||
expect(response.aggregations.gridSplit.buckets.length).to.equal(13);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,7 +9,6 @@ import expect from '@kbn/expect';
|
|||
|
||||
export default function ({ getPageObjects, getService }) {
|
||||
const PageObjects = getPageObjects(['maps']);
|
||||
const inspector = getService('inspector');
|
||||
const security = getService('security');
|
||||
|
||||
const VECTOR_SOURCE_ID = '67c1de2c-2fc5-4425-8983-094b589afe61';
|
||||
|
@ -25,15 +24,8 @@ export default function ({ getPageObjects, getService }) {
|
|||
});
|
||||
|
||||
it('should request source clusters for destination locations', async () => {
|
||||
await inspector.open();
|
||||
await inspector.openInspectorRequestsView();
|
||||
const requestStats = await inspector.getTableData();
|
||||
const hits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits');
|
||||
const totalHits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits (total)');
|
||||
await inspector.close();
|
||||
|
||||
expect(hits).to.equal('0');
|
||||
expect(totalHits).to.equal('4');
|
||||
const response = await PageObjects.maps.getResponse();
|
||||
expect(response.aggregations.destSplit.buckets.length).to.equal(2);
|
||||
});
|
||||
|
||||
it('should render lines', async () => {
|
||||
|
|
|
@ -121,17 +121,8 @@ export default function ({ getPageObjects, getService }) {
|
|||
});
|
||||
|
||||
it('should not apply query to source and apply query to join', async () => {
|
||||
await PageObjects.maps.openInspectorRequest('meta_for_geo_shapes*.shape_name');
|
||||
const requestStats = await inspector.getTableData();
|
||||
const totalHits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits (total)');
|
||||
expect(totalHits).to.equal('3');
|
||||
const hits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits');
|
||||
expect(hits).to.equal('0'); // aggregation requests do not return any documents
|
||||
const indexPatternName = PageObjects.maps.getInspectorStatRowHit(
|
||||
requestStats,
|
||||
'Index pattern'
|
||||
);
|
||||
expect(indexPatternName).to.equal('meta_for_geo_shapes*');
|
||||
const joinResponse = await PageObjects.maps.getResponse('meta_for_geo_shapes*.shape_name');
|
||||
expect(joinResponse.aggregations.join.buckets.length).to.equal(2);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -145,13 +136,8 @@ export default function ({ getPageObjects, getService }) {
|
|||
});
|
||||
|
||||
it('should apply query to join request', async () => {
|
||||
await PageObjects.maps.openInspectorRequest('meta_for_geo_shapes*.shape_name');
|
||||
const requestStats = await inspector.getTableData();
|
||||
const totalHits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits (total)');
|
||||
expect(totalHits).to.equal('2');
|
||||
const hits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits');
|
||||
expect(hits).to.equal('0'); // aggregation requests do not return any documents
|
||||
await inspector.close();
|
||||
const joinResponse = await PageObjects.maps.getResponse('meta_for_geo_shapes*.shape_name');
|
||||
expect(joinResponse.aggregations.join.buckets.length).to.equal(1);
|
||||
});
|
||||
|
||||
it('should update dynamic data range in legend with new results', async () => {
|
||||
|
|
|
@ -23,6 +23,8 @@ export function GisPageProvider({ getService, getPageObjects }: FtrProviderConte
|
|||
const browser = getService('browser');
|
||||
const MenuToggle = getService('MenuToggle');
|
||||
const listingTable = getService('listingTable');
|
||||
const monacoEditor = getService('monacoEditor');
|
||||
const dashboardPanelActions = getService('dashboardPanelActions');
|
||||
|
||||
const setViewPopoverToggle = new MenuToggle({
|
||||
name: 'SetView Popover',
|
||||
|
@ -614,6 +616,31 @@ export function GisPageProvider({ getService, getPageObjects }: FtrProviderConte
|
|||
return mapboxStyle;
|
||||
}
|
||||
|
||||
async getResponse(requestName: string) {
|
||||
await inspector.open();
|
||||
const response = await this._getResponse(requestName);
|
||||
await inspector.close();
|
||||
return response;
|
||||
}
|
||||
|
||||
async _getResponse(requestName: string) {
|
||||
if (requestName) {
|
||||
await testSubjects.click('inspectorRequestChooser');
|
||||
await testSubjects.click(`inspectorRequestChooser${requestName}`);
|
||||
}
|
||||
await inspector.openInspectorRequestsView();
|
||||
await testSubjects.click('inspectorRequestDetailResponse');
|
||||
const responseBody = await monacoEditor.getCodeEditorValue();
|
||||
return JSON.parse(responseBody);
|
||||
}
|
||||
|
||||
async getResponseFromDashboardPanel(panelTitle: string, requestName: string) {
|
||||
await dashboardPanelActions.openInspectorByTitle(panelTitle);
|
||||
const response = await this._getResponse(requestName);
|
||||
await inspector.close();
|
||||
return response;
|
||||
}
|
||||
|
||||
getInspectorStatRowHit(stats: string[][], rowName: string) {
|
||||
const STATS_ROW_NAME_INDEX = 0;
|
||||
const STATS_ROW_VALUE_INDEX = 1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue