Commit 0e38828a by Rashid Khan

Merge pull request #372 from rashidkpc/master

Fields from mapping, fixed sorting on different timezones
parents a8c9af65 39fa135f
...@@ -4,15 +4,82 @@ ...@@ -4,15 +4,82 @@
'use strict'; 'use strict';
angular.module('kibana.services', []) angular.module('kibana.services', [])
.service('fields', function() { .service('fields', function(dashboard, $rootScope, $http) {
// Save a reference to this // Save a reference to this
var self = this; var self = this;
this.list = ['_type']; this.list = ['_type'];
this.mapping = {};
this.add_fields = function(f) { this.add_fields = function(f) {
self.list = _.union(f,self.list); //self.list = _.union(f,self.list);
};
$rootScope.$watch(function(){return dashboard.indices;},function(n) {
if(!_.isUndefined(n) && n.length) {
// Only get the mapping for indices we don't know it for
var indices = _.difference(n,_.keys(self.mapping));
// Only get the mapping if there are indices
if(indices.length > 0) {
self.map(indices).then(function(result) {
self.mapping = _.extend(self.mapping,result);
self.list = mapFields(self.mapping);
});
// Otherwise just use the cached mapping
} else {
self.list = mapFields(_.pick(self.mapping,n));
}
}
});
var mapFields = function (m) {
var fields = [];
_.each(m, function(types,index) {
_.each(types, function(v,k) {
fields = _.union(fields,_.keys(v));
});
});
return fields;
};
this.map = function(indices) {
var request = $http({
url: config.elasticsearch + "/" + indices.join(',') + "/_mapping",
method: "GET"
});
return request.then(function(p) {
var mapping = {};
_.each(p.data, function(v,k) {
mapping[k] = {};
_.each(v, function (v,f) {
mapping[k][f] = flatten(v);
});
});
return mapping;
});
};
var flatten = function(obj,prefix) {
var propName = (prefix) ? prefix : '',
dot = (prefix) ? '.':'',
ret = {};
for(var attr in obj){
// For now only support multi field on the top level
// and if if there is a default field set.
if(obj[attr]['type'] === 'multi_field') {
ret[attr] = obj[attr]['fields'][attr] || obj[attr];
continue;
}
if (attr === 'properties') {
_.extend(ret,flatten(obj[attr], propName));
} else if(typeof obj[attr] === 'object'){
_.extend(ret,flatten(obj[attr], propName + dot + attr));
} else {
ret[propName] = obj;
}
}
return ret;
}; };
}) })
...@@ -383,6 +450,7 @@ angular.module('kibana.services', []) ...@@ -383,6 +450,7 @@ angular.module('kibana.services', [])
}; };
// This special function looks for all time filters, and returns a time range according to the mode // This special function looks for all time filters, and returns a time range according to the mode
// No idea when max would actually be used
this.timeRange = function(mode) { this.timeRange = function(mode) {
var _t = _.where(self.list,{type:'time',active:true}); var _t = _.where(self.list,{type:'time',active:true});
if(_t.length === 0) { if(_t.length === 0) {
......
...@@ -71,39 +71,6 @@ ...@@ -71,39 +71,6 @@
return value; return value;
}; };
// Probably useless now, leaving for cases where you might not want
// a flat dot notated data structure
kbn.get_field_value = function(object,field,opt) {
var value = kbn.recurse_field_dots(object._source,field);
if(value === null) {
return '';
}
if(_.isArray(value)) {
if (opt === 'raw') {
return value;
} else {
var complex = false;
_.each(value, function(el, index) {
if (typeof(el) === 'object') {
complex = true;
}
});
if (complex) {
return JSON.stringify(value, null, 4);
}
return value.toString();
}
}
if(typeof value === 'object' && value !== null) {
// Leaving this out for now
//return opt == 'raw' ? value : JSON.stringify(value,null,4)
return JSON.stringify(value,null,4);
}
return (value !== null) ? value.toString() : '';
};
kbn.top_field_values = function(docs,field,count) { kbn.top_field_values = function(docs,field,count) {
var counts = _.countBy(_.pluck(docs,field),function(field){ var counts = _.countBy(_.pluck(docs,field),function(field){
return _.isUndefined(field) ? '' : field; return _.isUndefined(field) ? '' : field;
......
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
<div ng-class="{'span3':panel.field_list}" ng-show="panel.field_list"> <div ng-class="{'span3':panel.field_list}" ng-show="panel.field_list">
<div class="sidebar-nav"> <div class="sidebar-nav">
<h5>Fields <i class=" icon-chevron-sign-left pointer " ng-click="panel.field_list = !panel.field_list" bs-tooltip="'Hide field list'" ng-show="panel.field_list"></i></h5> <h5>Fields <i class=" icon-chevron-sign-left pointer " ng-click="panel.field_list = !panel.field_list" bs-tooltip="'Hide field list'" ng-show="panel.field_list"></i></h5>
<ul class="unstyled" style="height:{{row.height}};overflow-y:auto;overflow-x:hidden;"> <ul class="unstyled" style="{{panel.overflow}}:{{panel.height || row.height}};overflow-y:auto;overflow-x:hidden;">
<li ng-style="panel.style" ng-repeat="field in all_fields" > <li ng-style="panel.style" ng-repeat="field in fields.list" >
<i class="pointer" ng-class="{'icon-check': _.contains(panel.fields,field),'icon-check-empty': !_.contains(panel.fields,field)}" ng-click="toggle_field(field)"></i> <i class="pointer" ng-class="{'icon-check': _.contains(panel.fields,field),'icon-check-empty': !_.contains(panel.fields,field)}" ng-click="toggle_field(field)"></i>
<a data-unique="1" bs-popover="'panels/table/micropanel.html'" data-placement="right" ng-click="toggle_micropanel(field)" ng-class="{label: _.contains(panel.fields,field)}">{{field}}</a> <a data-unique="1" bs-popover="'panels/table/micropanel.html'" data-placement="right" ng-click="toggle_micropanel(field)" ng-class="{label: _.contains(panel.fields,field)}">{{field}}</a>
</li> </li>
......
...@@ -61,6 +61,7 @@ angular.module('kibana.table', []) ...@@ -61,6 +61,7 @@ angular.module('kibana.table', [])
$scope.$on('refresh',function(){$scope.get_data();}); $scope.$on('refresh',function(){$scope.get_data();});
$scope.fields = fields;
$scope.get_data(); $scope.get_data();
}; };
...@@ -188,7 +189,11 @@ angular.module('kibana.table', []) ...@@ -188,7 +189,11 @@ angular.module('kibana.table', [])
$scope.data= $scope.data.concat(_.map(results.hits.hits, function(hit) { $scope.data= $scope.data.concat(_.map(results.hits.hits, function(hit) {
return { return {
_source : kbn.flatten_json(hit._source), _source : kbn.flatten_json(hit._source),
highlight : kbn.flatten_json(hit.highlight||{}) highlight : kbn.flatten_json(hit.highlight||{}),
_type : hit._type,
_index : hit._index,
_id : hit._id,
_sort : hit.sort
}; };
})); }));
...@@ -196,7 +201,7 @@ angular.module('kibana.table', []) ...@@ -196,7 +201,7 @@ angular.module('kibana.table', [])
// Sort the data // Sort the data
$scope.data = _.sortBy($scope.data, function(v){ $scope.data = _.sortBy($scope.data, function(v){
return v._source[$scope.panel.sort[0]]; return v._sort[0];
}); });
// Reverse if needed // Reverse if needed
...@@ -210,15 +215,12 @@ angular.module('kibana.table', []) ...@@ -210,15 +215,12 @@ angular.module('kibana.table', [])
} else { } else {
return; return;
} }
$scope.all_fields = kbn.get_all_fields(_.pluck($scope.data,'_source'));
fields.add_fields($scope.all_fields);
// If we're not sorting in reverse chrono order, query every index for // If we're not sorting in reverse chrono order, query every index for
// size*pages results // size*pages results
// Otherwise, only get size*pages results then stop querying // Otherwise, only get size*pages results then stop querying
//($scope.data.length < $scope.panel.size*$scope.panel.pages //($scope.data.length < $scope.panel.size*$scope.panel.pages
// || !(($scope.panel.sort[0] === $scope.time.field) && $scope.panel.sort[1] === 'desc')) // || !(($scope.panel.sort[0] === $scope.time.field) && $scope.panel.sort[1] === 'desc'))
if($scope.data.length < $scope.panel.size*$scope.panel.pages && if($scope.data.length < $scope.panel.size*$scope.panel.pages &&
_segment+1 < dashboard.indices.length ) { _segment+1 < dashboard.indices.length ) {
$scope.get_data(_segment+1,$scope.query_id); $scope.get_data(_segment+1,$scope.query_id);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment