From ca93dbb0867ff58eceddfb1a56105ac7f16f85ac Mon Sep 17 00:00:00 2001 From: Court Ewing Date: Wed, 18 Nov 2015 14:45:58 -0500 Subject: [PATCH] Avoid indices that do not have the configured time field The field stats api can, in certain situations, return an index even when that index does not contain any field that matches the configured time field name in the index pattern. We filter those out and treat it as if they were never returned at all. --- .../__tests__/calculate_indices.js | 16 ++++++++++++++-- .../index_patterns/_calculate_indices.js | 19 +++++++++++++++---- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/ui/public/index_patterns/__tests__/calculate_indices.js b/src/ui/public/index_patterns/__tests__/calculate_indices.js index 0347afae47d8..d5c44ec2d00c 100644 --- a/src/ui/public/index_patterns/__tests__/calculate_indices.js +++ b/src/ui/public/index_patterns/__tests__/calculate_indices.js @@ -12,11 +12,13 @@ describe('ui/index_patterns/_calculate_indices', () => { let response; let config; let constraints; + let indices; beforeEach(ngMock.module('kibana', ($provide) => { response = { indices: { - 'mock-*': 'irrelevant, is ignored' + 'mock-*': { fields: { '@something': {} } }, + 'ignore-*': { fields: {} } } }; @@ -37,7 +39,9 @@ describe('ui/index_patterns/_calculate_indices', () => { })); function run({ start = undefined, stop = undefined } = {}) { - calculateIndices('wat-*-no', '@something', start, stop); + calculateIndices('wat-*-no', '@something', start, stop).then(value => { + indices = value; + }); $rootScope.$apply(); config = _.first(es.fieldStats.lastCall.args); constraints = config.body.index_constraints; @@ -104,6 +108,14 @@ describe('ui/index_patterns/_calculate_indices', () => { }); }); + describe('response filtering', () => { + it('filters out any indices that have empty fields', () => { + run(); + expect(_.includes(indices, 'mock-*')).to.be(true); + expect(_.includes(indices, 'ignore-*')).to.be(false); + }); + }); + describe('response sorting', function () { require('testUtils/noDigestPromises').activateForSuite(); diff --git a/src/ui/public/index_patterns/_calculate_indices.js b/src/ui/public/index_patterns/_calculate_indices.js index 5b5adce73afc..9401e1d923ec 100644 --- a/src/ui/public/index_patterns/_calculate_indices.js +++ b/src/ui/public/index_patterns/_calculate_indices.js @@ -15,6 +15,15 @@ define(function (require) { }; } + // returns a new object with any indexes removed that do not include the + // time field + // + // fixme: this really seems like a bug that needs to be fixed in + // elasticsearch itself, but this workaround will do for now + function omitIndicesWithoutTimeField(indices, timeFieldName) { + return _.pick(indices, index => index.fields[timeFieldName]); + } + return function CalculateIndicesFactory(Promise, es) { // Uses the field stats api to determine the names of indices that need to @@ -22,7 +31,9 @@ define(function (require) { // given time range function calculateIndices(pattern, timeFieldName, start, stop, sortDirection) { return getFieldStats(pattern, timeFieldName, start, stop) - .then(resp => sortIndexStats(resp, timeFieldName, sortDirection)); + .then(resp => resp.indices) + .then(indices => omitIndicesWithoutTimeField(indices, timeFieldName)) + .then(indices => sortIndexStats(indices, timeFieldName, sortDirection)); }; // creates the configuration hash that must be passed to the elasticsearch @@ -48,14 +59,14 @@ define(function (require) { }); } - function sortIndexStats(resp, timeFieldName, sortDirection) { - if (!sortDirection) return _.keys(resp.indices); + function sortIndexStats(indices, timeFieldName, sortDirection) { + if (!sortDirection) return _.keys(indices); // FIXME: Once https://github.com/elastic/elasticsearch/issues/14404 is closed // this should be sorting based on the sortable value of a field. const edgeKey = sortDirection === 'desc' ? 'max_value' : 'min_value'; - return _(resp.indices) + return _(indices) .map((stats, index) => ( { index, edge: stats.fields[timeFieldName][edgeKey] } ))