import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
import org.apache.commons.lang.BooleanUtils;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
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.global.Global;
+import org.elasticsearch.search.aggregations.bucket.global.GlobalBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogram;
import org.elasticsearch.search.aggregations.bucket.missing.InternalMissing;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.issue.IssueQuery;
import org.sonar.server.issue.filter.IssueFilterParameters;
+import org.sonar.server.rule.index.RuleNormalizer;
+import org.sonar.server.search.IndexDefinition;
import org.sonar.server.search.StickyFacetBuilder;
import org.sonar.server.user.UserSession;
import org.sonar.server.view.index.ViewIndexDefinition;
*/
public class IssueIndex extends BaseIndex {
+ private static final String SUBSTRING_MATCH_REGEXP = ".*%s.*";
+
public static final List<String> SUPPORTED_FACETS = ImmutableList.of(
IssueFilterParameters.SEVERITIES,
IssueFilterParameters.STATUSES,
}
public List<String> listTags(IssueQuery query, @Nullable String textQuery, int maxNumberOfTags) {
- Terms terms = listTermsMatching(IssueIndexDefinition.FIELD_ISSUE_TAGS, query, textQuery, Terms.Order.term(true), maxNumberOfTags);
- return EsUtils.termsKeys(terms);
+ SearchRequestBuilder requestBuilder = getClient()
+ .prepareSearch(IssueIndexDefinition.INDEX, IndexDefinition.RULE.getIndexName())
+ .setTypes(IssueIndexDefinition.TYPE_ISSUE, IndexDefinition.RULE.getIndexType());
+
+ requestBuilder.setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(),
+ createBoolFilter(query)));
+ GlobalBuilder topAggreg = AggregationBuilders.global("tags");
+ TermsBuilder issueTags = AggregationBuilders.terms("tags__issues")
+ .field(IssueIndexDefinition.FIELD_ISSUE_TAGS)
+ .size(maxNumberOfTags)
+ .order(Terms.Order.term(true))
+ .minDocCount(1L);
+ if (textQuery != null) {
+ issueTags.include(String.format(SUBSTRING_MATCH_REGEXP, textQuery));
+ }
+ TermsBuilder ruleTags = AggregationBuilders.terms("tags__rules")
+ .field(RuleNormalizer.RuleField.ALL_TAGS.field())
+ .size(maxNumberOfTags)
+ .order(Terms.Order.term(true))
+ .minDocCount(1L);
+ if (textQuery != null) {
+ ruleTags.include(String.format(SUBSTRING_MATCH_REGEXP, textQuery));
+ }
+
+ SearchResponse searchResponse = requestBuilder.addAggregation(topAggreg.subAggregation(issueTags).subAggregation(ruleTags)).get();
+ Global allTags = searchResponse.getAggregations().get("tags");
+ SortedSet<String> result = Sets.newTreeSet();
+ Terms issuesResult = allTags.getAggregations().get("tags__issues");
+ Terms rulesResult = allTags.getAggregations().get("tags__rules");
+ result.addAll(EsUtils.termsKeys(issuesResult));
+ result.addAll(EsUtils.termsKeys(rulesResult));
+ List<String> resultAsList = Lists.newArrayList(result);
+ return resultAsList.size() > maxNumberOfTags ? resultAsList.subList(0, maxNumberOfTags) : resultAsList;
}
public Map<String, Long> countTags(IssueQuery query, int maxNumberOfTags) {
.order(termsOrder)
.minDocCount(1L);
if (textQuery != null) {
- aggreg.include(String.format(".*%s.*", textQuery));
+ aggreg.include(String.format(SUBSTRING_MATCH_REGEXP, textQuery));
}
SearchResponse searchResponse = requestBuilder.addAggregation(aggreg).get();
saveIssue(IssueTesting.newDto(rule, file, project));
saveIssue(IssueTesting.newDto(rule, file, project).setTags(ImmutableSet.of("convention")));
- assertThat(service.listTags(null, 5)).containsOnly("convention", "java8", "bug");
+ assertThat(service.listTags(null, 5)).containsOnly("convention", "java8", "bug" /* from issues */, "systag1", "systag2" /* from rules */);
assertThat(service.listTags(null, 2)).containsOnly("bug", "convention");
assertThat(service.listTags("vent", 5)).containsOnly("convention");
+ assertThat(service.listTags("sys", 5)).containsOnly("systag1", "systag2");
assertThat(service.listTags(null, 1)).containsOnly("bug");
- assertThat(service.listTags(null, Integer.MAX_VALUE)).containsOnly("convention", "java8", "bug");
+ assertThat(service.listTags(null, Integer.MAX_VALUE)).containsOnly("convention", "java8", "bug", "systag1", "systag2", "tag1", "tag2");
}
@Test