diff --git a/js/services.js b/js/services.js index ec51c226ec8e8..f286a86fa8f1e 100644 --- a/js/services.js +++ b/js/services.js @@ -4,15 +4,82 @@ 'use strict'; angular.module('kibana.services', []) -.service('fields', function() { - +.service('fields', function(dashboard, $rootScope, $http) { // Save a reference to this var self = this; this.list = ['_type']; + this.mapping = {}; 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', []) }; // 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) { var _t = _.where(self.list,{type:'time',active:true}); if(_t.length === 0) { diff --git a/js/shared.js b/js/shared.js index 91e457bb98220..ba0b2e2f8ceda 100644 --- a/js/shared.js +++ b/js/shared.js @@ -71,39 +71,6 @@ 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) { var counts = _.countBy(_.pluck(docs,field),function(field){ return _.isUndefined(field) ? '' : field; diff --git a/panels/table/module.html b/panels/table/module.html index 5abe68c5a436b..8a62c1fa91408 100644 --- a/panels/table/module.html +++ b/panels/table/module.html @@ -15,8 +15,8 @@