mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
This commit is contained in:
parent
8fdea1ab74
commit
e874b404da
3 changed files with 40 additions and 41 deletions
|
@ -6,7 +6,17 @@
|
|||
|
||||
import _ from 'lodash';
|
||||
|
||||
export function hitsToGeoJson(hits, geoFieldName, geoFieldType) {
|
||||
/**
|
||||
* Converts Elasticsearch search results into GeoJson FeatureCollection
|
||||
*
|
||||
* @param {array} hits Elasticsearch search response hits array
|
||||
* @param {function} flattenHit Method to flatten hits._source and hits.fields into properties object.
|
||||
* Should just be IndexPattern.flattenHit but wanted to avoid coupling this method to IndexPattern.
|
||||
* @param {string} geoFieldName Geometry field name
|
||||
* @param {string} geoFieldType Geometry field type ["geo_point", "geo_shape"]
|
||||
* @returns {number}
|
||||
*/
|
||||
export function hitsToGeoJson(hits, flattenHit, geoFieldName, geoFieldType) {
|
||||
const features = [];
|
||||
hits.forEach(hit => {
|
||||
const value = _.get(hit, `_source[${geoFieldName}]`);
|
||||
|
@ -19,22 +29,9 @@ export function hitsToGeoJson(hits, geoFieldName, geoFieldType) {
|
|||
throw new Error(`Unsupported field type, expected: geo_shape or geo_point, you provided: ${geoFieldType}`);
|
||||
}
|
||||
|
||||
const properties = {};
|
||||
for (const fieldName in hit._source) {
|
||||
if (hit._source.hasOwnProperty(fieldName)) {
|
||||
if (fieldName !== geoFieldName) {
|
||||
properties[fieldName] = hit._source[fieldName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// hit.fields contains calculated values from docvalue_fields and script_fields
|
||||
for (const fieldName in hit.fields) {
|
||||
if (hit.fields.hasOwnProperty(fieldName)) {
|
||||
const val = hit.fields[fieldName];
|
||||
properties[fieldName] = Array.isArray(val) && val.length === 1 ? val[0] : val;
|
||||
}
|
||||
}
|
||||
const properties = flattenHit(hit);
|
||||
// don't include geometry field value in properties
|
||||
delete properties[geoFieldName];
|
||||
|
||||
return geometries.map(geometry => {
|
||||
features.push({
|
||||
|
|
|
@ -20,6 +20,18 @@ const mapExtent = {
|
|||
minLon: -89,
|
||||
};
|
||||
|
||||
const flattenHitMock = hit => {
|
||||
const properties = {};
|
||||
for (const fieldName in hit._source) {
|
||||
if (hit._source.hasOwnProperty(fieldName)) {
|
||||
if (fieldName !== geoFieldName) {
|
||||
properties[fieldName] = hit._source[fieldName];
|
||||
}
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
};
|
||||
|
||||
describe('hitsToGeoJson', () => {
|
||||
it('Should convert elasitcsearch hits to geojson', () => {
|
||||
const hits = [
|
||||
|
@ -34,7 +46,7 @@ describe('hitsToGeoJson', () => {
|
|||
}
|
||||
},
|
||||
];
|
||||
const geojson = hitsToGeoJson(hits, geoFieldName, 'geo_point');
|
||||
const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point');
|
||||
expect(geojson.type).toBe('FeatureCollection');
|
||||
expect(geojson.features.length).toBe(2);
|
||||
expect(geojson.features[0]).toEqual({
|
||||
|
@ -58,12 +70,12 @@ describe('hitsToGeoJson', () => {
|
|||
_source: {}
|
||||
},
|
||||
];
|
||||
const geojson = hitsToGeoJson(hits, geoFieldName, 'geo_point');
|
||||
const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point');
|
||||
expect(geojson.type).toBe('FeatureCollection');
|
||||
expect(geojson.features.length).toBe(1);
|
||||
});
|
||||
|
||||
it('Should populate properties from _source and fields', () => {
|
||||
it('Should populate properties from hit', () => {
|
||||
const hits = [
|
||||
{
|
||||
_source: {
|
||||
|
@ -75,28 +87,10 @@ describe('hitsToGeoJson', () => {
|
|||
}
|
||||
}
|
||||
];
|
||||
const geojson = hitsToGeoJson(hits, geoFieldName, 'geo_point');
|
||||
const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point');
|
||||
expect(geojson.features.length).toBe(1);
|
||||
const feature = geojson.features[0];
|
||||
expect(feature.properties.myField).toBe(8);
|
||||
expect(feature.properties.myScriptedField).toBe(10);
|
||||
});
|
||||
|
||||
it('Should unwrap computed fields', () => {
|
||||
const hits = [
|
||||
{
|
||||
_source: {
|
||||
[geoFieldName]: { lat: 20, lon: 100 },
|
||||
},
|
||||
fields: {
|
||||
myScriptedField: [ 10 ] // script_fields are returned in an array
|
||||
}
|
||||
}
|
||||
];
|
||||
const geojson = hitsToGeoJson(hits, geoFieldName, 'geo_point');
|
||||
expect(geojson.features.length).toBe(1);
|
||||
const feature = geojson.features[0];
|
||||
expect(feature.properties.myScriptedField).toBe(10);
|
||||
});
|
||||
|
||||
it('Should create feature per item when geometry value is an array', () => {
|
||||
|
@ -111,7 +105,7 @@ describe('hitsToGeoJson', () => {
|
|||
}
|
||||
},
|
||||
];
|
||||
const geojson = hitsToGeoJson(hits, geoFieldName, 'geo_point');
|
||||
const geojson = hitsToGeoJson(hits, flattenHitMock, geoFieldName, 'geo_point');
|
||||
expect(geojson.type).toBe('FeatureCollection');
|
||||
expect(geojson.features.length).toBe(2);
|
||||
expect(geojson.features[0]).toEqual({
|
||||
|
|
|
@ -149,8 +149,16 @@ export class ESSearchSource extends VectorSource {
|
|||
}
|
||||
|
||||
let featureCollection;
|
||||
const flattenHit = hit => {
|
||||
const properties = indexPattern.flattenHit(hit);
|
||||
// remove metaFields
|
||||
indexPattern.metaFields.forEach(metaField => {
|
||||
delete properties[metaField];
|
||||
});
|
||||
return properties;
|
||||
};
|
||||
try {
|
||||
featureCollection = hitsToGeoJson(resp.hits.hits, geoField.name, geoField.type);
|
||||
featureCollection = hitsToGeoJson(resp.hits.hits, flattenHit, geoField.name, geoField.type);
|
||||
} catch(error) {
|
||||
throw new Error(`Unable to convert search response to geoJson feature collection, error: ${error.message}`);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue