diff --git a/public/app/plugins/datasource/elasticsearch/datasource.js b/public/app/plugins/datasource/elasticsearch/datasource.js index 20aa399bb2d..8f72dea25e9 100644 --- a/public/app/plugins/datasource/elasticsearch/datasource.js +++ b/public/app/plugins/datasource/elasticsearch/datasource.js @@ -127,173 +127,6 @@ function (angular, _, config, kbn, moment, ElasticQueryBuilder) { }); }; - ElasticDatasource.prototype._getDashboardWithSlug = function(id) { - return this._get('/dashboard/' + kbn.slugifyForUrl(id)) - .then(function(result) { - return angular.fromJson(result._source.dashboard); - }, function() { - throw "Dashboard not found"; - }); - }; - - ElasticDatasource.prototype.getDashboard = function(id, isTemp) { - var url = '/dashboard/' + id; - if (isTemp) { url = '/temp/' + id; } - - var self = this; - return this._get(url) - .then(function(result) { - return angular.fromJson(result._source.dashboard); - }, function(data) { - if(data.status === 0) { - throw "Could not contact Elasticsearch. Please ensure that Elasticsearch is reachable from your browser."; - } else { - // backward compatible fallback - return self._getDashboardWithSlug(id); - } - }); - }; - - ElasticDatasource.prototype.saveDashboard = function(dashboard) { - var title = dashboard.title; - var temp = dashboard.temp; - if (temp) { delete dashboard.temp; } - - var data = { - user: 'guest', - group: 'guest', - title: title, - tags: dashboard.tags, - dashboard: angular.toJson(dashboard) - }; - - if (temp) { - return this._saveTempDashboard(data); - } - else { - - var id = encodeURIComponent(kbn.slugifyForUrl(title)); - var self = this; - - return this._request('PUT', '/dashboard/' + id, this.index, data) - .then(function(results) { - self._removeUnslugifiedDashboard(results, title, id); - return { title: title, url: '/dashboard/db/' + id }; - }, function() { - throw 'Failed to save to elasticsearch'; - }); - } - }; - - ElasticDatasource.prototype._removeUnslugifiedDashboard = function(saveResult, title, id) { - if (saveResult.statusText !== 'Created') { return; } - if (title === id) { return; } - - var self = this; - this._get('/dashboard/' + title).then(function() { - self.deleteDashboard(title); - }); - }; - - ElasticDatasource.prototype._saveTempDashboard = function(data) { - return this._request('POST', '/temp/?ttl=' + this.saveTempTTL, this.index, data) - .then(function(result) { - - var baseUrl = window.location.href.replace(window.location.hash,''); - var url = baseUrl + "#dashboard/temp/" + result.data._id; - - return { title: data.title, url: url }; - - }, function(err) { - throw "Failed to save to temp dashboard to elasticsearch " + err.data; - }); - }; - - ElasticDatasource.prototype.deleteDashboard = function(id) { - return this._request('DELETE', '/dashboard/' + id, this.index) - .then(function(result) { - return result.data._id; - }, function(err) { - throw err.data; - }); - }; - - ElasticDatasource.prototype.searchDashboards = function(queryString) { - var endsInOpen = function(string, opener, closer) { - var character; - var count = 0; - for (var i = 0, len = string.length; i < len; i++) { - character = string[i]; - - if (character === opener) { - count++; - } else if (character === closer) { - count--; - } - } - - return count > 0; - }; - - var tagsOnly = queryString.indexOf('tags!:') === 0; - if (tagsOnly) { - var tagsQuery = queryString.substring(6, queryString.length); - queryString = 'tags:' + tagsQuery + '*'; - } - else { - if (queryString.length === 0) { - queryString = 'title:'; - } - - // make this a partial search if we're not in some reserved portion of the language, comments on conditionals, in order: - // 1. ends in reserved character, boosting, boolean operator ( -foo) - // 2. typing a reserved word like AND, OR, NOT - // 3. open parens (groupiing) - // 4. open " (term phrase) - // 5. open [ (range) - // 6. open { (range) - // see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax - if (!queryString.match(/(\*|\]|}|~|\)|"|^\d+|\s[\-+]\w+)$/) && - !queryString.match(/[A-Z]$/) && - !endsInOpen(queryString, '(', ')') && - !endsInOpen(queryString, '"', '"') && - !endsInOpen(queryString, '[', ']') && !endsInOpen(queryString, '[', '}') && - !endsInOpen(queryString, '{', ']') && !endsInOpen(queryString, '{', '}') - ){ - queryString += '*'; - } - } - - var query = { - query: { query_string: { query: queryString } }, - facets: { tags: { terms: { field: "tags", order: "term", size: 50 } } }, - size: 10000, - sort: ["_uid"], - }; - - return this._post('/dashboard/_search', query) - .then(function(results) { - if(_.isUndefined(results.hits)) { - return { dashboards: [], tags: [] }; - } - - var resultsHits = results.hits.hits; - var displayHits = { dashboards: [], tags: results.facets.tags.terms || [] }; - - for (var i = 0, len = resultsHits.length; i < len; i++) { - var hit = resultsHits[i]; - displayHits.dashboards.push({ - id: hit._id, - title: hit._source.title, - tags: hit._source.tags - }); - } - - displayHits.tagsOnly = tagsOnly; - return displayHits; - }); - }; - ElasticDatasource.prototype.testDatasource = function() { var query = JSON.stringify(); return this._post('/_search?search_type=count', query).then(function() { diff --git a/public/app/plugins/datasource/elasticsearch/partials/query.editor.html b/public/app/plugins/datasource/elasticsearch/partials/query.editor.html index 84028675ce5..b7ec5b75488 100644 --- a/public/app/plugins/datasource/elasticsearch/partials/query.editor.html +++ b/public/app/plugins/datasource/elasticsearch/partials/query.editor.html @@ -1,151 +1,129 @@ -
+
+ - + - + - + -
-
+
+
-
- +
+ -
-
+
+
-
- +
+ -
-
+
+
-
- +
+
-
- +
+ -
-
+
+
diff --git a/public/app/plugins/datasource/elasticsearch/plugin.json b/public/app/plugins/datasource/elasticsearch/plugin.json index bd467222a93..0ee7c036494 100644 --- a/public/app/plugins/datasource/elasticsearch/plugin.json +++ b/public/app/plugins/datasource/elasticsearch/plugin.json @@ -12,5 +12,6 @@ "annotations": "app/plugins/datasource/elasticsearch/partials/annotations.editor.html" }, - "annotations": true + "annotations": true, + "metrics": true } diff --git a/public/app/plugins/datasource/elasticsearch/queryCtrl.js b/public/app/plugins/datasource/elasticsearch/queryCtrl.js index ab40fc30f19..e5f47d95ce5 100644 --- a/public/app/plugins/datasource/elasticsearch/queryCtrl.js +++ b/public/app/plugins/datasource/elasticsearch/queryCtrl.js @@ -19,8 +19,6 @@ function (angular, _, ElasticQueryBuilder) { $scope.init = function() { var target = $scope.target; target.function = target.function || 'mean'; - target.tags = target.tags || []; - target.groupByTags = target.groupByTags || []; $scope.queryBuilder = new ElasticQueryBuilder(target); @@ -145,23 +143,6 @@ function (angular, _, ElasticQueryBuilder) { $scope.target.rawQuery = !$scope.target.rawQuery; }; - $scope.moveMetricQuery = function(fromIndex, toIndex) { - _.move($scope.panel.targets, fromIndex, toIndex); - }; - - $scope.duplicate = function() { - var clone = angular.copy($scope.target); - $scope.panel.targets.push(clone); - }; - - $scope.getMeasurements = function () { - var query = $scope.queryBuilder.buildExploreQuery('MEASUREMENTS'); - return $scope.datasource.metricFindQuery(query) - .then($scope.transformToSegments) - .then($scope.addTemplateVariableSegments) - .then(null, $scope.handleQueryError); - }; - $scope.handleQueryError = function(err) { $scope.parserError = err.message || 'Failed to issue metric query'; return []; @@ -180,159 +161,7 @@ function (angular, _, ElasticQueryBuilder) { return segments; }; - $scope.getTagsOrValues = function(segment, index) { - var query; - - if (segment.type === 'key' || segment.type === 'plus-button') { - query = $scope.queryBuilder.buildExploreQuery('TAG_KEYS'); - } else if (segment.type === 'value') { - query = $scope.queryBuilder.buildExploreQuery('TAG_VALUES', $scope.tagSegments[index-2].value); - } else if (segment.type === 'condition') { - return $q.when([new MetricSegment('AND'), new MetricSegment('OR')]); - } - else { - return $q.when([]); - } - - return $scope.datasource.metricFindQuery(query) - .then($scope.transformToSegments) - .then($scope.addTemplateVariableSegments) - .then(function(results) { - if (segment.type === 'key') { - results.splice(0, 0, angular.copy($scope.removeTagFilterSegment)); - } - return results; - }) - .then(null, $scope.handleQueryError); - }; - - $scope.getGroupByTagSegments = function(segment) { - var query = $scope.queryBuilder.buildExploreQuery('TAG_KEYS'); - - return $scope.datasource.metricFindQuery(query) - .then($scope.transformToSegments) - .then($scope.addTemplateVariableSegments) - .then(function(results) { - if (segment.type !== 'plus-button') { - results.splice(0, 0, angular.copy($scope.removeGroupBySegment)); - } - return results; - }) - .then(null, $scope.handleQueryError); - }; - - $scope.tagSegmentUpdated = function(segment, index) { - $scope.tagSegments[index] = segment; - - // handle remove tag condition - if (segment.value === $scope.removeTagFilterSegment.value) { - $scope.tagSegments.splice(index, 3); - if ($scope.tagSegments.length === 0) { - $scope.tagSegments.push(MetricSegment.newPlusButton()); - } else if ($scope.tagSegments.length > 2) { - $scope.tagSegments.splice(Math.max(index-1, 0), 1); - if ($scope.tagSegments[$scope.tagSegments.length-1].type !== 'plus-button') { - $scope.tagSegments.push(MetricSegment.newPlusButton()); - } - } - } - else { - if (segment.type === 'plus-button') { - if (index > 2) { - $scope.tagSegments.splice(index, 0, MetricSegment.newCondition('AND')); - } - $scope.tagSegments.push(MetricSegment.newOperator('=')); - $scope.tagSegments.push(MetricSegment.newFake('select tag value', 'value', 'query-segment-value')); - segment.type = 'key'; - segment.cssClass = 'query-segment-key'; - } - - if ((index+1) === $scope.tagSegments.length) { - $scope.tagSegments.push(MetricSegment.newPlusButton()); - } - } - - $scope.rebuildTargetTagConditions(); - }; - - $scope.rebuildTargetTagConditions = function() { - var tags = []; - var tagIndex = 0; - _.each($scope.tagSegments, function(segment2, index) { - if (segment2.type === 'key') { - if (tags.length === 0) { - tags.push({}); - } - tags[tagIndex].key = segment2.value; - } - else if (segment2.type === 'value') { - tags[tagIndex].value = segment2.value; - $scope.tagSegments[index-1] = $scope.getTagValueOperator(segment2.value); - } - else if (segment2.type === 'condition') { - tags.push({ condition: segment2.value }); - tagIndex += 1; - } - }); - - $scope.target.tags = tags; - $scope.$parent.get_data(); - }; - - $scope.getTagValueOperator = function(tagValue) { - if (tagValue[0] === '/' && tagValue[tagValue.length - 1] === '/') { - return MetricSegment.newOperator('=~'); - } - - return MetricSegment.newOperator('='); - }; - - function MetricSegment(options) { - if (options === '*' || options.value === '*') { - this.value = '*'; - this.html = $sce.trustAsHtml(''); - this.expandable = true; - return; - } - - if (_.isString(options)) { - this.value = options; - this.html = $sce.trustAsHtml(this.value); - return; - } - - this.cssClass = options.cssClass; - this.type = options.type; - this.fake = options.fake; - this.value = options.value; - this.type = options.type; - this.expandable = options.expandable; - this.html = options.html || $sce.trustAsHtml(templateSrv.highlightVariablesAsHtml(this.value)); - } - - MetricSegment.newSelectMeasurement = function() { - return new MetricSegment({value: 'select measurement', fake: true}); - }; - - MetricSegment.newFake = function(text, type, cssClass) { - return new MetricSegment({value: text, fake: true, type: type, cssClass: cssClass}); - }; - - MetricSegment.newCondition = function(condition) { - return new MetricSegment({value: condition, type: 'condition', cssClass: 'query-keyword' }); - }; - - MetricSegment.newOperator = function(op) { - return new MetricSegment({value: op, type: 'operator', cssClass: 'query-segment-operator' }); - }; - - MetricSegment.newPlusButton = function() { - return new MetricSegment({fake: true, html: '', type: 'plus-button' }); - }; - - MetricSegment.newSelectTagValue = function() { - return new MetricSegment({value: 'select tag value', fake: true}); - }; + $scope.init(); });