-
Notifications
You must be signed in to change notification settings - Fork 8.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix for #719 #732
Fix for #719 #732
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -129,7 +129,8 @@ function (angular, app, _, kbn, moment) { | |
}; | ||
|
||
$scope.toggle_micropanel = function(field,groups) { | ||
var docs = _.map($scope.data,function(_d){return _d.kibana._source;}); | ||
$scope.flattened_data = $scope.flattened_data || _.map($scope.data,function(_d){return kbn.flatten_json(_d.kibana._source); }); | ||
var docs = $scope.flattened_data; | ||
var topFieldValues = kbn.top_field_values(docs,field,10,groups); | ||
$scope.micropanel = { | ||
field: field, | ||
|
@@ -183,6 +184,10 @@ function (angular, app, _, kbn, moment) { | |
$scope.get_data(); | ||
}; | ||
|
||
$scope.flatten = function(obj) { | ||
return kbn.flatten_json(obj); | ||
}; | ||
|
||
$scope.build_search = function(field,value,negate) { | ||
var query; | ||
// This needs to be abstracted somewhere | ||
|
@@ -202,7 +207,34 @@ function (angular, app, _, kbn, moment) { | |
filterSrv.set({type:'exists',field:field,mandate:mandate}); | ||
}; | ||
|
||
$scope.get_data = function(segment,query_id) { | ||
$scope.compute_fields = function(state) { | ||
$scope.panelMeta.loading = true; | ||
|
||
var cb = function(results) { | ||
$scope.panelMeta.loading = false; | ||
|
||
// Check for error and abort if found | ||
if(!(_.isUndefined(results.error))) { | ||
$scope.panel.error = $scope.parse_error(results.error); | ||
return; | ||
} | ||
$scope.update_current_fields(results.hits.hits); | ||
// thank you, good bye | ||
}; | ||
|
||
$scope.do_search($scope.segment, $scope.query_id, cb); | ||
|
||
return state; | ||
}; | ||
|
||
$scope.update_current_fields = function(hits) { | ||
_.each(hits, function(hit) { | ||
$scope.current_fields = $scope.current_fields.concat(_.keys(kbn.flatten_json(hit._source))); | ||
}); | ||
$scope.current_fields = _.uniq($scope.current_fields); | ||
}; | ||
|
||
$scope.do_search = function(segment, query_id, cb) { | ||
var | ||
_segment, | ||
request, | ||
|
@@ -248,14 +280,18 @@ function (angular, app, _, kbn, moment) { | |
$scope.populate_modal(request); | ||
|
||
results = request.doSearch(); | ||
results.then(cb); | ||
}; | ||
|
||
// Populate scope when we have results | ||
results.then(function(results) { | ||
|
||
$scope.get_data = function(segment, query_id) { | ||
var cb = function(results) { | ||
$scope.panelMeta.loading = false; | ||
|
||
if(_segment === 0) { | ||
if($scope.segment === 0) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why does segment need to be attached to $scope? Is it being used somewhere outside of the controller? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know, because segment is already attached to $scope (https://github.com/elasticsearch/kibana/blob/master/src/app/panels/table/module.js#L222) This refactor came as I extracted the callback from get_data. Maybe we can refactor even more to remove the variable from $scope |
||
$scope.hits = 0; | ||
$scope.data = []; | ||
$scope.flattened_data = null; | ||
$scope.current_fields = []; | ||
query_id = $scope.query_id = new Date().getTime(); | ||
} | ||
|
@@ -268,6 +304,10 @@ function (angular, app, _, kbn, moment) { | |
|
||
// Check that we're still on the same query, if not stop | ||
if($scope.query_id === query_id) { | ||
// Update field list immediately if visible | ||
if($scope.panel.field_list && $scope.current_fields !== []) { | ||
$scope.update_current_fields(results.hits.hits); | ||
} | ||
|
||
// This is exceptionally expensive, especially on events with a large number of fields | ||
$scope.data = $scope.data.concat(_.map(results.hits.hits, function(hit) { | ||
|
@@ -277,17 +317,13 @@ function (angular, app, _, kbn, moment) { | |
|
||
// _source is kind of a lie here, never display it, only select values from it | ||
_h.kibana = { | ||
_source : _.extend(kbn.flatten_json(hit._source),_p), | ||
_source : _.extend(hit._source,_p), | ||
highlight : kbn.flatten_json(hit.highlight||{}) | ||
}; | ||
|
||
// Kind of cheating with the _.map here, but this is faster than kbn.get_all_fields | ||
$scope.current_fields = $scope.current_fields.concat(_.keys(_h.kibana._source)); | ||
|
||
return _h; | ||
})); | ||
|
||
$scope.current_fields = _.uniq($scope.current_fields); | ||
$scope.hits += results.hits.total; | ||
|
||
// Sort the data | ||
|
@@ -316,11 +352,13 @@ function (angular, app, _, kbn, moment) { | |
// Otherwise, only get size*pages results then stop querying | ||
if (($scope.data.length < $scope.panel.size*$scope.panel.pages || | ||
!((_.contains(filterSrv.timeField(),$scope.panel.sort[0])) && $scope.panel.sort[1] === 'desc')) && | ||
_segment+1 < dashboard.indices.length) { | ||
$scope.get_data(_segment+1,$scope.query_id); | ||
$scope.segment+1 < dashboard.indices.length) { | ||
$scope.get_data($scope.segment+1,$scope.query_id); | ||
} | ||
|
||
}); | ||
}; | ||
|
||
$scope.do_search(segment, query_id, cb); | ||
}; | ||
|
||
$scope.populate_modal = function(request) { | ||
|
@@ -357,8 +395,33 @@ function (angular, app, _, kbn, moment) { | |
} | ||
return obj; | ||
}; | ||
}); | ||
|
||
module.filter('fromSources', function() { | ||
return function(fieldName, source1, source2) { | ||
var findField = function(segments, into) { | ||
var where = into; | ||
var found = true; | ||
var segment; | ||
|
||
for(var seg in segments ) { | ||
segment = segments[seg]; | ||
if(where[segment]) { | ||
where = where[segment]; | ||
} else { | ||
found = false; | ||
break; | ||
} | ||
} | ||
if(found) { | ||
return where; | ||
} | ||
return null; | ||
}; | ||
var segments = fieldName.split(/\./); | ||
|
||
return findField(segments, source1) || findField(segments, source2); | ||
}; | ||
}); | ||
|
||
// This also escapes some xml sequences | ||
|
@@ -386,8 +449,6 @@ function (angular, app, _, kbn, moment) { | |
}; | ||
}); | ||
|
||
|
||
|
||
module.filter('tableJson', function() { | ||
var json; | ||
return function(text,prettyLevel) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is considered a bad practice in angular. flatten will need to be evaluated on every digest. As the user opens more rows this will get expensive quickly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, but is this worse than flattening all rows at once when the table renders initially ?
Maybe the code could refactored much more so that it flattens all rows when needed, once, when opening the fields list, showing a row as a table, or micro-analysing a facet. And still, we don't need to flatten all rows when just showing a single row as a table
Right now, my knowledge of angular is pretty much experimental, hence the bad practice result :/ What's your opinion ?