mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[maps] fix sort not applied to vector tile search request (#134607)
* [maps] fix sort not applied to vector tile search request * clean up * clean comment * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * fix jest, integration, and functional test Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
7cbd0bf15d
commit
b7c8ff5d7b
6 changed files with 57 additions and 70 deletions
|
@ -82,47 +82,11 @@ export function getHitsTileRequest({
|
|||
exact_bounds: true,
|
||||
extent: 4096, // full resolution,
|
||||
query: requestBody.query,
|
||||
fields: mergeFields(
|
||||
[
|
||||
requestBody.docvalue_fields as Field[] | undefined,
|
||||
requestBody.stored_fields as Field[] | undefined,
|
||||
],
|
||||
[geometryFieldName]
|
||||
),
|
||||
fields: requestBody.fields ? requestBody.fields : [],
|
||||
runtime_mappings: requestBody.runtime_mappings,
|
||||
sort: requestBody.sort ? requestBody.sort : [],
|
||||
track_total_hits: typeof requestBody.size === 'number' ? requestBody.size + 1 : false,
|
||||
with_labels: hasLabels,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// can not use "import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey"
|
||||
// SearchRequest is incorrectly typed and does not support Field as object
|
||||
// https://github.com/elastic/elasticsearch-js/issues/1615
|
||||
type Field =
|
||||
| string
|
||||
| {
|
||||
field: string;
|
||||
format: string;
|
||||
};
|
||||
|
||||
function mergeFields(fieldsList: Array<Field[] | undefined>, excludeNames: string[]): Field[] {
|
||||
const fieldNames: string[] = [];
|
||||
const mergedFields: Field[] = [];
|
||||
|
||||
fieldsList.forEach((fields) => {
|
||||
if (!fields) {
|
||||
return;
|
||||
}
|
||||
|
||||
fields.forEach((field) => {
|
||||
const fieldName = typeof field === 'string' ? field : field.field;
|
||||
if (!excludeNames.includes(fieldName) && !fieldNames.includes(fieldName)) {
|
||||
fieldNames.push(fieldName);
|
||||
mergedFields.push(field);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return mergedFields;
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ describe('ESSearchSource', () => {
|
|||
});
|
||||
const tileUrl = await esSearchSource.getTileUrl(searchFilters, '1234', false);
|
||||
expect(tileUrl).toBe(
|
||||
`rootdir/api/maps/mvt/getTile/{z}/{x}/{y}.pbf?geometryFieldName=bar&index=foobar-title-*&hasLabels=false&requestBody=(foobar%3AES_DSL_PLACEHOLDER%2Cparams%3A('0'%3A('0'%3Aindex%2C'1'%3A(fields%3A()%2Ctitle%3A'foobar-title-*'))%2C'1'%3A('0'%3Asize%2C'1'%3A1000)%2C'2'%3A('0'%3Afilter%2C'1'%3A!())%2C'3'%3A('0'%3Aquery)%2C'4'%3A('0'%3Aindex%2C'1'%3A(fields%3A()%2Ctitle%3A'foobar-title-*'))%2C'5'%3A('0'%3Aquery%2C'1'%3A(language%3AKQL%2Cquery%3A'tooltipField%3A%20foobar'))%2C'6'%3A('0'%3AfieldsFromSource%2C'1'%3A!(tooltipField%2CstyleField))%2C'7'%3A('0'%3Asource%2C'1'%3A!(tooltipField%2CstyleField))))&token=1234`
|
||||
`rootdir/api/maps/mvt/getTile/{z}/{x}/{y}.pbf?geometryFieldName=bar&index=foobar-title-*&hasLabels=false&requestBody=(foobar%3AES_DSL_PLACEHOLDER%2Cparams%3A('0'%3A('0'%3Aindex%2C'1'%3A(fields%3A()%2Ctitle%3A'foobar-title-*'))%2C'1'%3A('0'%3Asize%2C'1'%3A1000)%2C'2'%3A('0'%3Afilter%2C'1'%3A!())%2C'3'%3A('0'%3Aquery)%2C'4'%3A('0'%3Aindex%2C'1'%3A(fields%3A()%2Ctitle%3A'foobar-title-*'))%2C'5'%3A('0'%3Aquery%2C'1'%3A(language%3AKQL%2Cquery%3A'tooltipField%3A%20foobar'))%2C'6'%3A('0'%3AfieldsFromSource%2C'1'%3A!(_id))%2C'7'%3A('0'%3Asource%2C'1'%3A!f)%2C'8'%3A('0'%3Afields%2C'1'%3A!(tooltipField%2CstyleField))))&token=1234`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -827,41 +827,50 @@ export class ESSearchSource extends AbstractESSource implements IMvtVectorSource
|
|||
const indexPattern = await this.getIndexPattern();
|
||||
const indexSettings = await loadIndexSettings(indexPattern.title);
|
||||
|
||||
const fieldNames = searchFilters.fieldNames.filter(
|
||||
(fieldName) => fieldName !== this._descriptor.geoField
|
||||
);
|
||||
const { docValueFields, sourceOnlyFields } = getDocValueAndSourceFields(
|
||||
indexPattern,
|
||||
fieldNames,
|
||||
'epoch_millis'
|
||||
);
|
||||
|
||||
const initialSearchContext = { docvalue_fields: docValueFields }; // Request fields in docvalue_fields insted of _source
|
||||
|
||||
const searchSource = await this.makeSearchSource(
|
||||
searchFilters,
|
||||
indexSettings.maxResultWindow,
|
||||
initialSearchContext
|
||||
);
|
||||
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
|
||||
} else {
|
||||
searchSource.setField('source', sourceOnlyFields);
|
||||
}
|
||||
const searchSource = await this.makeSearchSource(searchFilters, indexSettings.maxResultWindow);
|
||||
// searchSource calls dataView.getComputedFields to seed docvalueFields
|
||||
// dataView.getComputedFields adds each date field in the dataView to docvalueFields to ensure standardized date format across kibana
|
||||
// we don't need these as they request unneeded fields and bloat responses
|
||||
// setting fieldsFromSource notifies searchSource to filterout unused docvalueFields
|
||||
// '_id' is used since the value of 'fieldsFromSource' is irreverent because '_source: false'.
|
||||
searchSource.setField('fieldsFromSource', ['_id']);
|
||||
searchSource.setField('source', false);
|
||||
if (this._hasSort()) {
|
||||
searchSource.setField('sort', this._buildEsSort());
|
||||
}
|
||||
|
||||
// use fields API
|
||||
searchSource.setField(
|
||||
'fields',
|
||||
searchFilters.fieldNames
|
||||
.filter((fieldName) => {
|
||||
return fieldName !== this._descriptor.geoField;
|
||||
})
|
||||
.map((fieldName) => {
|
||||
const field = indexPattern.fields.getByName(fieldName);
|
||||
return field && field.type === 'date'
|
||||
? {
|
||||
field: fieldName,
|
||||
format: 'epoch_millis',
|
||||
}
|
||||
: fieldName;
|
||||
})
|
||||
);
|
||||
|
||||
const mvtUrlServicePath = getHttp().basePath.prepend(
|
||||
`/${GIS_API_PATH}/${MVT_GETTILE_API_PATH}/{z}/{x}/{y}.pbf`
|
||||
);
|
||||
|
||||
const requestBody = searchSource.getSearchRequestBody();
|
||||
// Remove keys not supported by elasticsearch vector tile search API
|
||||
delete requestBody.script_fields;
|
||||
delete requestBody.stored_fields;
|
||||
|
||||
return `${mvtUrlServicePath}\
|
||||
?geometryFieldName=${this._descriptor.geoField}\
|
||||
&index=${indexPattern.title}\
|
||||
&hasLabels=${hasLabels}\
|
||||
&requestBody=${encodeMvtResponseBody(searchSource.getSearchRequestBody())}\
|
||||
&requestBody=${encodeMvtResponseBody(requestBody)}\
|
||||
&token=${refreshToken}`;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ test('Should return elasticsearch vector tile request for hits tiles', () => {
|
|||
expect(
|
||||
getTileRequest({
|
||||
layerId: '1',
|
||||
tileUrl: `http://localhost:5601/pof/api/maps/mvt/getTile/{z}/{x}/{y}.pbf?geometryFieldName=geo.coordinates&hasLabels=true&index=kibana_sample_data_logs&requestBody=(_source%3A!f%2Cdocvalue_fields%3A!()%2Cquery%3A(bool%3A(filter%3A!((range%3A(timestamp%3A(format%3Astrict_date_optional_time%2Cgte%3A%272022-04-22T16%3A46%3A00.744Z%27%2Clte%3A%272022-04-29T16%3A46%3A05.345Z%27))))%2Cmust%3A!()%2Cmust_not%3A!()%2Cshould%3A!()))%2Cruntime_mappings%3A(hour_of_day%3A(script%3A(source%3A%27emit(doc%5B!%27timestamp!%27%5D.value.getHour())%3B%27)%2Ctype%3Along))%2Cscript_fields%3A()%2Csize%3A10000%2Cstored_fields%3A!(geo.coordinates))&token=415049b6-bb0a-444a-a7b9-89717db5183c`,
|
||||
tileUrl: `http://localhost:5601/zuv/api/maps/mvt/getTile/4/2/6.pbf?geometryFieldName=geo.coordinates&index=kibana_sample_data_logs&hasLabels=true&requestBody=(_source%3A!f%2Cfields%3A!((field%3A%27%40timestamp%27%2Cformat%3Aepoch_millis)%2Cbytes)%2Cquery%3A(bool%3A(filter%3A!((range%3A(timestamp%3A(format%3Astrict_date_optional_time%2Cgte%3A%272022-06-15T20%3A00%3A00.000Z%27%2Clte%3A%272022-06-16T20%3A48%3A02.517Z%27))))%2Cmust%3A!()%2Cmust_not%3A!()%2Cshould%3A!()))%2Cruntime_mappings%3A(hour_of_day%3A(script%3A(source%3A%27emit(doc%5B!%27timestamp!%27%5D.value.getHour())%3B%27)%2Ctype%3Along))%2Csize%3A10000%2Csort%3A!((%27%40timestamp%27%3A(order%3Adesc%2Cunmapped_type%3Aboolean))))&token=7afe7c2d-c96b-4bdb-9b5e-819aceac80a1`,
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 2,
|
||||
|
@ -98,8 +98,8 @@ test('Should return elasticsearch vector tile request for hits tiles', () => {
|
|||
range: {
|
||||
timestamp: {
|
||||
format: 'strict_date_optional_time',
|
||||
gte: '2022-04-22T16:46:00.744Z',
|
||||
lte: '2022-04-29T16:46:05.345Z',
|
||||
gte: '2022-06-15T20:00:00.000Z',
|
||||
lte: '2022-06-16T20:48:02.517Z',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -109,7 +109,13 @@ test('Should return elasticsearch vector tile request for hits tiles', () => {
|
|||
should: [],
|
||||
},
|
||||
},
|
||||
fields: [],
|
||||
fields: [
|
||||
{
|
||||
field: '@timestamp',
|
||||
format: 'epoch_millis',
|
||||
},
|
||||
'bytes',
|
||||
],
|
||||
runtime_mappings: {
|
||||
hour_of_day: {
|
||||
script: {
|
||||
|
@ -118,6 +124,14 @@ test('Should return elasticsearch vector tile request for hits tiles', () => {
|
|||
type: 'long',
|
||||
},
|
||||
},
|
||||
sort: [
|
||||
{
|
||||
'@timestamp': {
|
||||
order: 'desc',
|
||||
unmapped_type: 'boolean',
|
||||
},
|
||||
},
|
||||
],
|
||||
track_total_hits: 10001,
|
||||
with_labels: true,
|
||||
},
|
||||
|
|
|
@ -29,7 +29,7 @@ export default function ({ getService }) {
|
|||
?geometryFieldName=geo.coordinates\
|
||||
&hasLabels=false\
|
||||
&index=logstash-*\
|
||||
&requestBody=(_source:!f,docvalue_fields:!(bytes,geo.coordinates,machine.os.raw,(field:'@timestamp',format:epoch_millis)),query:(bool:(filter:!((match_all:()),(range:(%27@timestamp%27:(format:strict_date_optional_time,gte:%272015-09-20T00:00:00.000Z%27,lte:%272015-09-20T01:00:00.000Z%27)))),must:!(),must_not:!(),should:!())),runtime_mappings:(),script_fields:(),size:10000,stored_fields:!(bytes,geo.coordinates,machine.os.raw,'@timestamp'))`
|
||||
&requestBody=(_source:!f,fields:!(bytes,machine.os.raw,(field:'@timestamp',format:epoch_millis)),query:(bool:(filter:!((match_all:()),(range:(%27@timestamp%27:(format:strict_date_optional_time,gte:%272015-09-20T00:00:00.000Z%27,lte:%272015-09-20T01:00:00.000Z%27)))),must:!(),must_not:!(),should:!())),runtime_mappings:(),size:10000)`
|
||||
)
|
||||
.set('kbn-xsrf', 'kibana')
|
||||
.responseType('blob')
|
||||
|
@ -93,7 +93,7 @@ export default function ({ getService }) {
|
|||
?geometryFieldName=geo.coordinates\
|
||||
&hasLabels=true\
|
||||
&index=logstash-*\
|
||||
&requestBody=(_source:!f,docvalue_fields:!(bytes,geo.coordinates,machine.os.raw,(field:'@timestamp',format:epoch_millis)),query:(bool:(filter:!((match_all:()),(range:(%27@timestamp%27:(format:strict_date_optional_time,gte:%272015-09-20T00:00:00.000Z%27,lte:%272015-09-20T01:00:00.000Z%27)))),must:!(),must_not:!(),should:!())),runtime_mappings:(),script_fields:(),size:10000,stored_fields:!(bytes,geo.coordinates,machine.os.raw,'@timestamp'))`
|
||||
&requestBody=(_source:!f,fields:!(bytes,machine.os.raw,(field:'@timestamp',format:epoch_millis)),query:(bool:(filter:!((match_all:()),(range:(%27@timestamp%27:(format:strict_date_optional_time,gte:%272015-09-20T00:00:00.000Z%27,lte:%272015-09-20T01:00:00.000Z%27)))),must:!(),must_not:!(),should:!())),runtime_mappings:(),size:10000)`
|
||||
)
|
||||
.set('kbn-xsrf', 'kibana')
|
||||
.responseType('blob')
|
||||
|
@ -138,7 +138,7 @@ export default function ({ getService }) {
|
|||
?geometryFieldName=geo.coordinates\
|
||||
&hasLabels=false\
|
||||
&index=notRealIndex\
|
||||
&requestBody=(_source:!f,docvalue_fields:!(bytes,geo.coordinates,machine.os.raw,(field:'@timestamp',format:epoch_millis)),query:(bool:(filter:!((match_all:()),(range:(%27@timestamp%27:(format:strict_date_optional_time,gte:%272015-09-20T00:00:00.000Z%27,lte:%272015-09-20T01:00:00.000Z%27)))),must:!(),must_not:!(),should:!())),runtime_mappings:(),script_fields:(),size:10000,stored_fields:!(bytes,geo.coordinates,machine.os.raw,'@timestamp'))`
|
||||
&requestBody=(_source:!f,fields:!(bytes,machine.os.raw,(field:'@timestamp',format:epoch_millis)),query:(bool:(filter:!((match_all:()),(range:(%27@timestamp%27:(format:strict_date_optional_time,gte:%272015-09-20T00:00:00.000Z%27,lte:%272015-09-20T01:00:00.000Z%27)))),must:!(),must_not:!(),should:!())),runtime_mappings:(),size:10000)`
|
||||
)
|
||||
.set('kbn-xsrf', 'kibana')
|
||||
.responseType('blob')
|
||||
|
|
|
@ -53,7 +53,7 @@ export default function ({ getPageObjects, getService }) {
|
|||
hasLabels: 'false',
|
||||
index: 'geo_shapes*',
|
||||
requestBody:
|
||||
'(_source:!f,docvalue_fields:!(prop1),query:(bool:(filter:!(),must:!(),must_not:!(),should:!())),runtime_mappings:(),script_fields:(),size:10001,stored_fields:!(geometry,prop1))',
|
||||
'(_source:!f,fields:!(prop1),query:(bool:(filter:!(),must:!(),must_not:!(),should:!())),runtime_mappings:(),size:10001)',
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue