aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>2014-10-30 16:10:46 +0100
committerJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>2014-10-30 16:16:44 +0100
commitbe93f8c42f7951ec1ff5851405c2dc6d786dd473 (patch)
treed3fe5223d4a0187f966dd50cffd0a97a906bda0f
parent6137d755bac7fa51b6b69546d5fccbb65dff25ad (diff)
downloadsonarqube-be93f8c42f7951ec1ff5851405c2dc6d786dd473.tar.gz
sonarqube-be93f8c42f7951ec1ff5851405c2dc6d786dd473.zip
SONAR-5718 Refactor sticky facet building
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java35
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndex.java7
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/search/BaseIndex.java60
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/search/StickyFacetBuilder.java107
4 files changed, 132 insertions, 77 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java
index 94f0ba2a837..fcb869847f4 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java
@@ -337,22 +337,23 @@ public class IssueIndex extends BaseIndex<Issue, IssueDto, String> {
private void setFacets(IssueQuery query, QueryContext options, Map<String, FilterBuilder> filters, QueryBuilder esQuery, SearchRequestBuilder esSearch) {
if (options.isFacet()) {
+ StickyFacetBuilder stickyFacetBuilder = stickyFacetBuilder(esQuery, filters);
// Execute Term aggregations
- addSimpleStickyFacetIfNeeded(query, options, filters, esQuery, esSearch,
+ addSimpleStickyFacetIfNeeded(options, stickyFacetBuilder, esSearch,
IssueFilterParameters.SEVERITIES, IssueNormalizer.IssueField.SEVERITY.field(), 0);
- addSimpleStickyFacetIfNeeded(query, options, filters, esQuery, esSearch,
+ addSimpleStickyFacetIfNeeded(options, stickyFacetBuilder, esSearch,
IssueFilterParameters.STATUSES, IssueNormalizer.IssueField.STATUS.field(), 0);
- addSimpleStickyFacetIfNeeded(query, options, filters, esQuery, esSearch,
+ addSimpleStickyFacetIfNeeded(options, stickyFacetBuilder, esSearch,
IssueFilterParameters.ACTION_PLANS, IssueNormalizer.IssueField.ACTION_PLAN.field(), 1, query.actionPlans().toArray());
- addSimpleStickyFacetIfNeeded(query, options, filters, esQuery, esSearch,
+ addSimpleStickyFacetIfNeeded(options, stickyFacetBuilder, esSearch,
IssueFilterParameters.COMPONENT_ROOT_UUIDS, IssueNormalizer.IssueField.MODULE_PATH.field(), 1, query.componentRootUuids().toArray());
- addSimpleStickyFacetIfNeeded(query, options, filters, esQuery, esSearch,
+ addSimpleStickyFacetIfNeeded(options, stickyFacetBuilder, esSearch,
IssueFilterParameters.COMPONENT_UUIDS, IssueNormalizer.IssueField.COMPONENT.field(), 1, query.componentUuids().toArray());
- addSimpleStickyFacetIfNeeded(query, options, filters, esQuery, esSearch,
+ addSimpleStickyFacetIfNeeded(options, stickyFacetBuilder, esSearch,
IssueFilterParameters.LANGUAGES, IssueNormalizer.IssueField.LANGUAGE.field(), 0, query.languages().toArray());
- addSimpleStickyFacetIfNeeded(query, options, filters, esQuery, esSearch,
+ addSimpleStickyFacetIfNeeded(options, stickyFacetBuilder, esSearch,
IssueFilterParameters.RULES, IssueNormalizer.IssueField.RULE_KEY.field(), 1, query.rules().toArray());
- addSimpleStickyFacetIfNeeded(query, options, filters, esQuery, esSearch,
+ addSimpleStickyFacetIfNeeded(options, stickyFacetBuilder, esSearch,
IssueFilterParameters.REPORTERS, IssueNormalizer.IssueField.REPORTER.field(), 1);
if (options.facets().contains(IssueFilterParameters.RESOLUTIONS)) {
@@ -364,10 +365,10 @@ public class IssueIndex extends BaseIndex<Issue, IssueDto, String> {
}
}
- private void addSimpleStickyFacetIfNeeded(IssueQuery query, QueryContext options, Map<String, FilterBuilder> filters, QueryBuilder esQuery, SearchRequestBuilder esSearch,
+ private void addSimpleStickyFacetIfNeeded(QueryContext options, StickyFacetBuilder stickyFacetBuilder, SearchRequestBuilder esSearch,
String facetName, String fieldName, int minDocCount, Object... selectedValues) {
if (options.facets().contains(facetName)) {
- esSearch.addAggregation(stickyFacetBuilder(esQuery, filters, fieldName, facetName, DEFAULT_ISSUE_FACET_SIZE, minDocCount, selectedValues));
+ esSearch.addAggregation(stickyFacetBuilder.buildStickyFacet(fieldName, facetName, DEFAULT_ISSUE_FACET_SIZE, minDocCount, selectedValues));
}
}
@@ -379,9 +380,10 @@ public class IssueIndex extends BaseIndex<Issue, IssueDto, String> {
Map<String, FilterBuilder> assigneeFilters = Maps.newHashMap(filters);
assigneeFilters.remove("__isAssigned");
assigneeFilters.remove(fieldName);
- BoolFilterBuilder facetFilter = getStickyFacetFilter(esQuery, assigneeFilters, fieldName);
- FilterAggregationBuilder facetTopAggregation = buildTopFacetAggregation(fieldName, facetName, facetFilter, DEFAULT_ISSUE_FACET_SIZE, 1);
- addSelectedItemsToFacet(fieldName, facetName, facetTopAggregation, query.assignees().toArray());
+ StickyFacetBuilder assigneeFacetBuilder = new StickyFacetBuilder(esQuery, assigneeFilters);
+ BoolFilterBuilder facetFilter = assigneeFacetBuilder.getStickyFacetFilter(fieldName);
+ FilterAggregationBuilder facetTopAggregation = assigneeFacetBuilder.buildTopFacetAggregation(fieldName, facetName, facetFilter, DEFAULT_ISSUE_FACET_SIZE, 1);
+ facetTopAggregation = assigneeFacetBuilder.addSelectedItemsToFacet(fieldName, facetName, facetTopAggregation, query.assignees().toArray());
// Add missing facet for unassigned issues
facetTopAggregation.subAggregation(
@@ -403,9 +405,10 @@ public class IssueIndex extends BaseIndex<Issue, IssueDto, String> {
Map<String, FilterBuilder> resolutionFilters = Maps.newHashMap(filters);
resolutionFilters.remove("__isResolved");
resolutionFilters.remove(fieldName);
- BoolFilterBuilder facetFilter = getStickyFacetFilter(esQuery, resolutionFilters, fieldName);
- FilterAggregationBuilder facetTopAggregation = buildTopFacetAggregation(fieldName, facetName, facetFilter, DEFAULT_ISSUE_FACET_SIZE, 0);
- addSelectedItemsToFacet(fieldName, facetName, facetTopAggregation, query.resolutions().toArray());
+ StickyFacetBuilder assigneeFacetBuilder = new StickyFacetBuilder(esQuery, resolutionFilters);
+ BoolFilterBuilder facetFilter = assigneeFacetBuilder.getStickyFacetFilter(fieldName);
+ FilterAggregationBuilder facetTopAggregation = assigneeFacetBuilder.buildTopFacetAggregation(fieldName, facetName, facetFilter, DEFAULT_ISSUE_FACET_SIZE, 0);
+ facetTopAggregation = assigneeFacetBuilder.addSelectedItemsToFacet(fieldName, facetName, facetTopAggregation, query.resolutions().toArray());
// Add missing facet for unresolved issues
facetTopAggregation.subAggregation(
diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndex.java b/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndex.java
index b1d4c86cd71..f87aa8ba4a0 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndex.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndex.java
@@ -318,9 +318,10 @@ public class RuleIndex extends BaseIndex<Rule, RuleDto, RuleKey> {
protected Map<String, AggregationBuilder> getFacets(QueryBuilder query, Map<String, FilterBuilder> filters) {
Map<String, AggregationBuilder> aggregations = new HashMap<String, AggregationBuilder>();
- aggregations.put(FACET_LANGUAGES + "global", stickyFacetBuilder(query, filters, RuleNormalizer.RuleField.LANGUAGE.field(), FACET_LANGUAGES));
- aggregations.put(FACET_TAGS + "global", stickyFacetBuilder(query, filters, RuleNormalizer.RuleField.ALL_TAGS.field(), FACET_TAGS));
- aggregations.put(FACET_REPOSITORIES + "global", stickyFacetBuilder(query, filters, RuleNormalizer.RuleField.REPOSITORY.field(), FACET_REPOSITORIES));
+ StickyFacetBuilder stickyFacetBuilder = stickyFacetBuilder(query, filters);
+ aggregations.put(FACET_LANGUAGES + "global", stickyFacetBuilder.buildStickyFacet(RuleNormalizer.RuleField.LANGUAGE.field(), FACET_LANGUAGES));
+ aggregations.put(FACET_TAGS + "global", stickyFacetBuilder.buildStickyFacet(RuleNormalizer.RuleField.ALL_TAGS.field(), FACET_TAGS));
+ aggregations.put(FACET_REPOSITORIES + "global", stickyFacetBuilder.buildStickyFacet(RuleNormalizer.RuleField.REPOSITORY.field(), FACET_REPOSITORIES));
return aggregations;
diff --git a/server/sonar-server/src/main/java/org/sonar/server/search/BaseIndex.java b/server/sonar-server/src/main/java/org/sonar/server/search/BaseIndex.java
index bded61a64e8..a179b88fbf7 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/search/BaseIndex.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/search/BaseIndex.java
@@ -19,12 +19,10 @@
*/
package org.sonar.server.search;
-import com.google.common.base.Joiner;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
-import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.action.count.CountRequestBuilder;
import org.elasticsearch.action.count.CountResponse;
@@ -38,10 +36,8 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.Aggregation;
-import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
-import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.max.Max;
@@ -62,10 +58,6 @@ import java.util.*;
public abstract class BaseIndex<DOMAIN, DTO extends Dto<KEY>, KEY extends Serializable>
implements Index<DOMAIN, DTO, KEY> {
- private static final int FACET_DEFAULT_MIN_DOC_COUNT = 1;
-
- private static final int FACET_DEFAULT_SIZE = 10;
-
private static final Logger LOG = LoggerFactory.getLogger(BaseIndex.class);
private final SearchClient client;
@@ -613,55 +605,7 @@ public abstract class BaseIndex<DOMAIN, DTO extends Dto<KEY>, KEY extends Serial
}
- protected AggregationBuilder stickyFacetBuilder(QueryBuilder query, Map<String, FilterBuilder> filters, String fieldName, String facetName,
- Object... selected) {
- return stickyFacetBuilder(query, filters, fieldName, facetName, FACET_DEFAULT_SIZE, FACET_DEFAULT_MIN_DOC_COUNT, selected);
- }
-
- protected AggregationBuilder stickyFacetBuilder(QueryBuilder query, Map<String, FilterBuilder> filters, String fieldName, String facetName, int size, int minDocCount,
- Object... selected) {
- BoolFilterBuilder facetFilter = getStickyFacetFilter(query, filters, fieldName);
- FilterAggregationBuilder facetTopAggregation = buildTopFacetAggregation(fieldName, facetName, facetFilter, size, minDocCount);
- facetTopAggregation = addSelectedItemsToFacet(fieldName, facetName, facetTopAggregation, selected);
-
- return AggregationBuilders
- .global(facetName)
- .subAggregation(facetTopAggregation);
- }
-
- protected BoolFilterBuilder getStickyFacetFilter(QueryBuilder query, Map<String, FilterBuilder> filters, String fieldName) {
- BoolFilterBuilder facetFilter = FilterBuilders.boolFilter().must(FilterBuilders.queryFilter(query));
- for (Map.Entry<String, FilterBuilder> filter : filters.entrySet()) {
- if (filter.getValue() != null && !StringUtils.equals(filter.getKey(), fieldName)) {
- facetFilter.must(filter.getValue());
- }
- }
- return facetFilter;
- }
-
- protected FilterAggregationBuilder buildTopFacetAggregation(String fieldName, String facetName, BoolFilterBuilder facetFilter, int size, int minDocCount) {
- return AggregationBuilders
- .filter(facetName + "_filter")
- .filter(facetFilter)
- .subAggregation(
- AggregationBuilders.terms(facetName)
- .field(fieldName)
- .order(Terms.Order.count(false))
- .size(size)
- .minDocCount(minDocCount));
- }
-
- protected FilterAggregationBuilder buildTopFacetAggregation(String fieldName, String facetName, BoolFilterBuilder facetFilter) {
- return buildTopFacetAggregation(fieldName, facetName, facetFilter, FACET_DEFAULT_SIZE, FACET_DEFAULT_MIN_DOC_COUNT);
- }
-
- protected FilterAggregationBuilder addSelectedItemsToFacet(String fieldName, String facetName, FilterAggregationBuilder facetTopAggregation, Object... selected) {
- if (selected.length > 0) {
- facetTopAggregation.subAggregation(
- AggregationBuilders.terms(facetName + "_selected")
- .field(fieldName)
- .include(Joiner.on('|').join(selected)));
- }
- return facetTopAggregation;
+ protected StickyFacetBuilder stickyFacetBuilder(QueryBuilder query, Map<String, FilterBuilder> filters) {
+ return new StickyFacetBuilder(query, filters);
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/search/StickyFacetBuilder.java b/server/sonar-server/src/main/java/org/sonar/server/search/StickyFacetBuilder.java
new file mode 100644
index 00000000000..09a16598be6
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/search/StickyFacetBuilder.java
@@ -0,0 +1,107 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.search;
+
+import com.google.common.base.Joiner;
+import org.apache.commons.lang.StringUtils;
+import org.elasticsearch.index.query.BoolFilterBuilder;
+import org.elasticsearch.index.query.FilterBuilder;
+import org.elasticsearch.index.query.FilterBuilders;
+import org.elasticsearch.index.query.QueryBuilder;
+import org.elasticsearch.search.aggregations.AggregationBuilder;
+import org.elasticsearch.search.aggregations.AggregationBuilders;
+import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
+import org.elasticsearch.search.aggregations.bucket.terms.Terms;
+
+import java.util.Map;
+
+public class StickyFacetBuilder {
+
+ private static final int FACET_DEFAULT_MIN_DOC_COUNT = 1;
+
+ private static final int FACET_DEFAULT_SIZE = 10;
+
+ private QueryBuilder query;
+
+ private Map<String, FilterBuilder> filters;
+
+ public StickyFacetBuilder(QueryBuilder query, Map<String, FilterBuilder> filters) {
+ this.query = query;
+ this.filters = filters;
+ }
+
+ public QueryBuilder query() {
+ return query;
+ }
+
+ public Map<String, FilterBuilder> filters() {
+ return filters;
+ }
+
+ public AggregationBuilder buildStickyFacet(String fieldName, String facetName, Object... selected) {
+ return buildStickyFacet(fieldName, facetName, FACET_DEFAULT_SIZE, FACET_DEFAULT_MIN_DOC_COUNT, selected);
+ }
+
+ public AggregationBuilder buildStickyFacet(String fieldName, String facetName, int size, int minDocCount, Object... selected) {
+ BoolFilterBuilder facetFilter = getStickyFacetFilter(fieldName);
+ FilterAggregationBuilder facetTopAggregation = buildTopFacetAggregation(fieldName, facetName, facetFilter, size, minDocCount);
+ facetTopAggregation = addSelectedItemsToFacet(fieldName, facetName, facetTopAggregation, selected);
+
+ return AggregationBuilders
+ .global(facetName)
+ .subAggregation(facetTopAggregation);
+ }
+
+ public BoolFilterBuilder getStickyFacetFilter(String fieldName) {
+ BoolFilterBuilder facetFilter = FilterBuilders.boolFilter().must(FilterBuilders.queryFilter(query));
+ for (Map.Entry<String, FilterBuilder> filter : filters.entrySet()) {
+ if (filter.getValue() != null && !StringUtils.equals(filter.getKey(), fieldName)) {
+ facetFilter.must(filter.getValue());
+ }
+ }
+ return facetFilter;
+ }
+
+ public FilterAggregationBuilder buildTopFacetAggregation(String fieldName, String facetName, BoolFilterBuilder facetFilter, int size, int minDocCount) {
+ return AggregationBuilders
+ .filter(facetName + "_filter")
+ .filter(facetFilter)
+ .subAggregation(
+ AggregationBuilders.terms(facetName)
+ .field(fieldName)
+ .order(Terms.Order.count(false))
+ .size(size)
+ .minDocCount(minDocCount));
+ }
+
+ protected FilterAggregationBuilder buildTopFacetAggregation(String fieldName, String facetName, BoolFilterBuilder facetFilter) {
+ return buildTopFacetAggregation(fieldName, facetName, facetFilter, FACET_DEFAULT_SIZE, FACET_DEFAULT_MIN_DOC_COUNT);
+ }
+
+ public FilterAggregationBuilder addSelectedItemsToFacet(String fieldName, String facetName, FilterAggregationBuilder facetTopAggregation, Object... selected) {
+ if (selected.length > 0) {
+ facetTopAggregation.subAggregation(
+ AggregationBuilders.terms(facetName + "_selected")
+ .field(fieldName)
+ .include(Joiner.on('|').join(selected)));
+ }
+ return facetTopAggregation;
+ }
+}