mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Check sort is valid before attempting to sort on it. Closes #2755
This commit is contained in:
parent
d7972bca28
commit
eaf11f1673
6 changed files with 70 additions and 40 deletions
|
@ -9,14 +9,29 @@ define(function (require) {
|
|||
*/
|
||||
return function (sort, indexPattern) {
|
||||
var sortObj = {};
|
||||
if (_.isArray(sort) && sort.length === 2) {
|
||||
var field, direction;
|
||||
|
||||
function isSortable(field) {
|
||||
return (indexPattern.fields.byName[field] && indexPattern.fields.byName[field].sortable);
|
||||
}
|
||||
|
||||
if (_.isArray(sort) && sort.length === 2 && isSortable(sort[0])) {
|
||||
// At some point we need to refact the sorting logic, this array sucks.
|
||||
sortObj[sort[0]] = sort[1];
|
||||
} else if (indexPattern.timeFieldName) {
|
||||
sortObj[indexPattern.timeFieldName] = 'desc';
|
||||
field = sort[0];
|
||||
direction = sort[1];
|
||||
} else if (indexPattern.timeFieldName && isSortable(indexPattern.timeFieldName)) {
|
||||
field = indexPattern.timeFieldName;
|
||||
direction = 'desc';
|
||||
}
|
||||
|
||||
if (field) {
|
||||
sortObj[field] = direction;
|
||||
} else {
|
||||
sortObj._score = 'desc';
|
||||
}
|
||||
|
||||
|
||||
|
||||
return sortObj;
|
||||
};
|
||||
});
|
||||
|
|
|
@ -425,15 +425,8 @@ define(function (require) {
|
|||
$scope.searchSource
|
||||
.size($scope.opts.sampleSize)
|
||||
.sort(function () {
|
||||
var sort = {};
|
||||
if (_.isArray($state.sort) && $state.sort.length === 2) {
|
||||
sort[$state.sort[0]] = $state.sort[1];
|
||||
} else if ($scope.indexPattern.timeFieldName) {
|
||||
// Use the watcher to set sort in this case, the above `if` will now be true
|
||||
$state.sort = [$scope.indexPattern.timeFieldName, 'desc'];
|
||||
} else {
|
||||
sort._score = 'desc';
|
||||
}
|
||||
var sort = getSort($state.sort, $scope.indexPattern);
|
||||
$state.sort = _.pairs(sort)[0];
|
||||
return sort;
|
||||
})
|
||||
.query(!$state.query ? null : $state.query)
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
define(function (require) {
|
||||
function stubbedLogstashFields() {
|
||||
var sourceData = [
|
||||
{ name: 'bytes', type: 'number', indexed: true, analyzed: true, count: 10 },
|
||||
{ name: 'ssl', type: 'boolean', indexed: true, analyzed: true, count: 20 },
|
||||
{ name: '@timestamp', type: 'date', indexed: true, analyzed: true, count: 30 },
|
||||
{ name: 'time', type: 'date', indexed: true, analyzed: true, count: 30 },
|
||||
{ name: 'utc_time', type: 'date', indexed: true, analyzed: true },
|
||||
{ name: 'phpmemory', type: 'number', indexed: true, analyzed: true },
|
||||
{ name: 'ip', type: 'ip', indexed: true, analyzed: true },
|
||||
{ name: 'request_body', type: 'attachment', indexed: true, analyzed: true },
|
||||
{ name: 'point', type: 'geo_point', indexed: true, analyzed: true },
|
||||
{ name: 'area', type: 'geo_shape', indexed: true, analyzed: true },
|
||||
{ name: 'extension', type: 'string', indexed: true, analyzed: true },
|
||||
{ name: 'machine.os', type: 'string', indexed: true, analyzed: true },
|
||||
{ name: 'geo.src', type: 'string', indexed: true, analyzed: true },
|
||||
{ name: '_type', type: 'string', indexed: true, analyzed: true },
|
||||
{ name: 'bytes', type: 'number', indexed: true, analyzed: true, sortable: true, filterable: true, count: 10 },
|
||||
{ name: 'ssl', type: 'boolean', indexed: true, analyzed: true, sortable: true, filterable: true, count: 20 },
|
||||
{ name: '@timestamp', type: 'date', indexed: true, analyzed: true, sortable: true, filterable: true, count: 30 },
|
||||
{ name: 'time', type: 'date', indexed: true, analyzed: true, sortable: true, filterable: true, count: 30 },
|
||||
{ name: 'utc_time', type: 'date', indexed: true, analyzed: true, sortable: true, filterable: true },
|
||||
{ name: 'phpmemory', type: 'number', indexed: true, analyzed: true, sortable: true, filterable: true },
|
||||
{ name: 'ip', type: 'ip', indexed: true, analyzed: true, sortable: true, filterable: true },
|
||||
{ name: 'request_body', type: 'attachment', indexed: true, analyzed: true, sortable: false, filterable: true },
|
||||
{ name: 'point', type: 'geo_point', indexed: true, analyzed: true, sortable: false, filterable: false },
|
||||
{ name: 'area', type: 'geo_shape', indexed: true, analyzed: true, sortable: true, filterable: false },
|
||||
{ name: 'extension', type: 'string', indexed: true, analyzed: true, sortable: true, filterable: true },
|
||||
{ name: 'machine.os', type: 'string', indexed: true, analyzed: true, sortable: true, filterable: true },
|
||||
{ name: 'geo.src', type: 'string', indexed: true, analyzed: true, sortable: true, filterable: true },
|
||||
{ name: '_type', type: 'string', indexed: true, analyzed: true, sortable: true, filterable: true },
|
||||
{ name: '_id', type: 'string', indexed: false, analyzed: false, sortable: false, filterable: true},
|
||||
{ name: 'custom_user_field', type: 'conflict', indexed: false, analyzed: false },
|
||||
{ name: 'script string', type: 'string', scripted: true, script: '\'i am a string\''},
|
||||
{ name: 'script number', type: 'number', scripted: true, script: '1234'},
|
||||
|
|
|
@ -4,30 +4,43 @@ define(function (require) {
|
|||
describe('docTable', function () {
|
||||
describe('getSort function', function () {
|
||||
|
||||
var timePattern = {
|
||||
timeFieldName: 'time'
|
||||
};
|
||||
var noTimePattern = {};
|
||||
beforeEach(module('kibana'));
|
||||
|
||||
beforeEach(inject(function (Private, _$rootScope_, Promise) {
|
||||
indexPattern = Private(require('fixtures/stubbed_logstash_index_pattern'));
|
||||
}));
|
||||
|
||||
it('should be a function', function () {
|
||||
expect(getSort).to.be.a(Function);
|
||||
});
|
||||
|
||||
it('should return an object if passed a 2 item array', function () {
|
||||
expect(getSort(['foo', 'bar'], timePattern)).to.eql({foo: 'bar'});
|
||||
expect(getSort(['foo', 'bar'], noTimePattern)).to.eql({foo: 'bar'});
|
||||
expect(getSort(['bytes', 'desc'], indexPattern)).to.eql({bytes: 'desc'});
|
||||
|
||||
delete indexPattern.timeFieldName;
|
||||
expect(getSort(['bytes', 'desc'], indexPattern)).to.eql({bytes: 'desc'});
|
||||
});
|
||||
|
||||
it('should sort by the default when passed an unsortable field', function () {
|
||||
expect(getSort(['_id', 'asc'], indexPattern)).to.eql({time: 'desc'});
|
||||
expect(getSort(['lol_nope', 'asc'], indexPattern)).to.eql({time: 'desc'});
|
||||
|
||||
delete indexPattern.timeFieldName;
|
||||
expect(getSort(['_id', 'asc'], indexPattern)).to.eql({_score: 'desc'});
|
||||
});
|
||||
|
||||
it('should sort in reverse chrono order otherwise on time based patterns', function () {
|
||||
expect(getSort([], timePattern)).to.eql({time: 'desc'});
|
||||
expect(getSort(['foo'], timePattern)).to.eql({time: 'desc'});
|
||||
expect(getSort({foo: 'bar'}, timePattern)).to.eql({time: 'desc'});
|
||||
expect(getSort([], indexPattern)).to.eql({time: 'desc'});
|
||||
expect(getSort(['foo'], indexPattern)).to.eql({time: 'desc'});
|
||||
expect(getSort({foo: 'bar'}, indexPattern)).to.eql({time: 'desc'});
|
||||
});
|
||||
|
||||
it('should sort by score on non-time patterns', function () {
|
||||
expect(getSort([], noTimePattern)).to.eql({_score: 'desc'});
|
||||
expect(getSort(['foo'], noTimePattern)).to.eql({_score: 'desc'});
|
||||
expect(getSort({foo: 'bar'}, noTimePattern)).to.eql({_score: 'desc'});
|
||||
delete indexPattern.timeFieldName;
|
||||
|
||||
expect(getSort([], indexPattern)).to.eql({_score: 'desc'});
|
||||
expect(getSort(['foo'], indexPattern)).to.eql({_score: 'desc'});
|
||||
expect(getSort({foo: 'bar'}, indexPattern)).to.eql({_score: 'desc'});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -102,7 +102,7 @@ define(function (require) {
|
|||
describe('getFields', function () {
|
||||
it('should return all non-scripted fields', function () {
|
||||
var indexed = _.where(mockLogstashFields, { scripted: false });
|
||||
expect(indexPattern.getFields()).to.eql(indexed);
|
||||
expect(indexPattern.getFields().length).to.eql(indexed.length);
|
||||
});
|
||||
|
||||
it('should return all scripted fields', function () {
|
||||
|
|
|
@ -4,6 +4,10 @@ define(function (require) {
|
|||
var sinon = require('sinon/sinon');
|
||||
var IndexedArray = require('utils/indexed_array/index');
|
||||
var fieldFormats = Private(require('components/index_patterns/_field_formats'));
|
||||
var flattenSearchResponse = require('components/index_patterns/_flatten_search_response');
|
||||
var flattenHit = require('components/index_patterns/_flatten_hit');
|
||||
var getComputedFields = require('components/index_patterns/_get_computed_fields');
|
||||
|
||||
|
||||
function StubIndexPattern(pattern, timeField, fields) {
|
||||
this.popularizeField = sinon.spy();
|
||||
|
@ -27,6 +31,10 @@ define(function (require) {
|
|||
});
|
||||
this.getFields = sinon.spy();
|
||||
this.toIndexList = _.constant([pattern]);
|
||||
this.getComputedFields = getComputedFields;
|
||||
this.flattenSearchResponse = flattenSearchResponse;
|
||||
this.flattenHit = flattenHit;
|
||||
this.metaFields = ['_id', '_type', '_source'];
|
||||
}
|
||||
|
||||
return StubIndexPattern;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue