import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.filters.FiltersAggregationBuilder;
+import org.elasticsearch.search.aggregations.bucket.filters.FiltersAggregator;
+import org.elasticsearch.search.aggregations.bucket.filters.FiltersAggregator.KeyedFilter;
import org.elasticsearch.search.aggregations.bucket.filters.InternalFilters;
import org.elasticsearch.search.aggregations.bucket.filters.InternalFilters.InternalBucket;
import org.elasticsearch.search.aggregations.metrics.tophits.InternalTopHits;
private static FiltersAggregationBuilder createAggregation(ComponentIndexQuery query) {
return AggregationBuilders.filters(
FILTERS_AGGREGATION_NAME,
- query.getQualifiers().stream().map(q -> termQuery(FIELD_QUALIFIER, q)).toArray(QueryBuilder[]::new))
+ query.getQualifiers().stream().map(q -> new KeyedFilter(q, termQuery(FIELD_QUALIFIER, q))).toArray(KeyedFilter[]::new))
.subAggregation(createSubAggregation(query));
}
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation.Bucket;
+import org.elasticsearch.search.aggregations.bucket.filters.FiltersAggregator;
import org.elasticsearch.search.aggregations.bucket.range.RangeAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
private static AbstractAggregationBuilder createRatingFacet(String metricKey) {
return AggregationBuilders.nested("nested_" + metricKey, FIELD_MEASURES)
.subAggregation(
- AggregationBuilders.filter("filter_" + metricKey, termsQuery(FIELD_MEASURES_KEY, metricKey))
- .subAggregation(filters(metricKey,
- termQuery(FIELD_MEASURES_VALUE, 1d),
- termQuery(FIELD_MEASURES_VALUE, 2d),
- termQuery(FIELD_MEASURES_VALUE, 3d),
- termQuery(FIELD_MEASURES_VALUE, 4d),
- termQuery(FIELD_MEASURES_VALUE, 5d))));
+ AggregationBuilders.filter("filter_" + metricKey, termsQuery(FIELD_MEASURES_KEY, metricKey))
+ .subAggregation(filters(metricKey,
+ new FiltersAggregator.KeyedFilter("1", termQuery(FIELD_MEASURES_VALUE, 1d)),
+ new FiltersAggregator.KeyedFilter("2", termQuery(FIELD_MEASURES_VALUE, 2d)),
+ new FiltersAggregator.KeyedFilter("3", termQuery(FIELD_MEASURES_VALUE, 3d)),
+ new FiltersAggregator.KeyedFilter("4", termQuery(FIELD_MEASURES_VALUE, 4d)),
+ new FiltersAggregator.KeyedFilter("5", termQuery(FIELD_MEASURES_VALUE, 5d)))));
}
private static AbstractAggregationBuilder createQualityGateFacet() {
}
private static StickyFacetBuilder stickyFacetBuilder(QueryBuilder query, Map<String, QueryBuilder> filters) {
- return new StickyFacetBuilder(query, filters);
+ return new StickyFacetBuilder(query, filters, null, Terms.Order.compound(Terms.Order.count(false), Terms.Order.term(true)));
}
private static void setSorting(RuleQuery query, SearchRequestBuilder esSearch) {
import static java.util.Collections.emptySet;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.sonar.db.component.ComponentTesting.newFileDto;
import static org.sonar.server.component.index.ComponentIndexDefinition.FIELD_NAME;
import static org.sonar.server.component.index.ComponentIndexDefinition.INDEX_TYPE_COMPONENT;
+import static org.sonar.server.es.DefaultIndexSettingsElement.SORTABLE_ANALYZER;
import static org.sonar.server.es.ProjectIndexer.Cause.PROJECT_CREATION;
import static org.sonar.server.es.ProjectIndexer.Cause.PROJECT_DELETION;
private void assertThatComponentHasName(ComponentDto component, String expectedName) {
SearchHit[] hits = es.client()
.prepareSearch(INDEX_TYPE_COMPONENT)
- .setQuery(termQuery(FIELD_NAME, expectedName))
+ .setQuery(matchQuery(SORTABLE_ANALYZER.subField(FIELD_NAME), expectedName))
.get()
.getHits()
.getHits();
assertThat(props.get("fields")).isNull();
props = (Map) mapping.getProperty("all_capabilities_field");
- assertThat(props.get("type")).isEqualTo("multi_field");
+ assertThat(props.get("type")).isEqualTo("keyword");
// no need to test values, it's not the scope of this test
assertThat((Map) props.get("fields")).isNotEmpty();
}
fail();
} catch (Exception e) {
assertThat(e).isInstanceOf(IllegalStateException.class);
- assertThat(e.getMessage()).contains("Fail to execute ES search request '{").contains("}' on indices '[fakes]'");
+ assertThat(e.getMessage()).contains("Fail to execute ES search request 'SearchRequest{").contains("}' on indices '[non-existing-index]'");
}
}
assertJson(result.toString()).isSimilarTo("{" +
" \"bool\" : {" +
- " \"must\" : {" +
+ " \"must\" : [{" +
" \"bool\" : {" +
- " \"should\" : {" +
+ " \"should\" : [{" +
" \"match\" : {" +
" \"key.sortable_analyzer\" : {" +
" \"query\" : \"SonarQube\"," +
- " \"type\" : \"boolean\"," +
" \"boost\" : 50.0\n" +
" }" +
" }" +
- " }" +
+ " }]" +
" }" +
- " }" +
+ " }]" +
" }" +
"}");
}
" \"has_parent\" : {" +
" \"query\" : {" +
" \"bool\" : {" +
- " \"filter\" : {" +
+ " \"filter\" : [{" +
" \"bool\" : {" +
- " \"should\" : {" +
+ " \"should\" : [{" +
" \"term\" : {" +
- " \"allowAnyone\" : true" +
+ " \"allowAnyone\" : {\"value\": true}" +
" }" +
- " }" +
+ " }]" +
" }" +
- " }" +
+ " }]" +
" }" +
" }," +
" \"parent_type\" : \"authorization\"" +
" \"has_parent\": {" +
" \"query\": {" +
" \"bool\": {" +
- " \"filter\": {" +
+ " \"filter\": [{" +
" \"bool\": {" +
" \"should\": [" +
" {" +
" \"term\": {" +
- " \"allowAnyone\": true" +
+ " \"allowAnyone\": {\"value\": true}" +
" }" +
" }," +
" {" +
" \"term\": {" +
- " \"userIds\": 1234" +
+ " \"userIds\": {\"value\": 1234}" +
" }" +
" }" +
" ]" +
" }" +
- " }" +
+ " }]" +
" }" +
" }," +
" \"parent_type\": \"authorization\"" +
" \"has_parent\": {" +
" \"query\": {" +
" \"bool\": {" +
- " \"filter\": {" +
+ " \"filter\": [{" +
" \"bool\": {" +
" \"should\": [" +
" {" +
" \"term\": {" +
- " \"allowAnyone\": true" +
+ " \"allowAnyone\": {\"value\": true}" +
" }" +
" }," +
" {" +
" \"term\": {" +
- " \"userIds\": 1234" +
+ " \"userIds\": {\"value\": 1234}" +
" }" +
" }," +
" {" +
" \"term\": {" +
- " \"groupIds\": 10" +
+ " \"groupIds\": {\"value\": 10}" +
" }" +
" }," +
" {" +
" \"term\": {" +
- " \"groupIds\": 11" +
+ " \"groupIds\": {\"value\": 11}" +
" }" +
" }" +
" ]" +
" }" +
- " }" +
+ " }]" +
" }" +
" }," +
" \"parent_type\": \"authorization\"" +
.setParam("facets", "tags")
.setParam("organization", organization.getKey())
.executeProtobuf(SearchResponse.class);
- assertThat(result.getFacets().getFacets(0).getValuesList()).extracting(v -> entry(v.getVal(), v.getCount()))
- .containsExactly(entry("tag1", 1L), entry("tag2", 1L), entry("tag3", 1L), entry("tag4", 1L), entry("tag5", 1L), entry("tag6", 1L), entry("tag7", 1L), entry("tag8", 1L),
- entry("tag9", 1L), entry("tagA", 1L));
+ assertThat(result.getFacets().getFacets(0).getValuesList()).extracting(v -> v.getVal(), v -> v.getCount())
+ .containsExactly(tuple("tag1", 1L), tuple("tag2", 1L), tuple("tag3", 1L), tuple("tag4", 1L), tuple("tag5", 1L), tuple("tag6", 1L), tuple("tag7", 1L), tuple("tag8", 1L),
+ tuple("tag9", 1L), tuple("tagA", 1L));
+ }
+
+ @Test
+ public void should_list_tags_ordered_by_count_then_by_name_in_tags_facet() throws IOException {
+ OrganizationDto organization = db.organizations().insert();
+ RuleDefinitionDto rule = db.rules().insert(setSystemTags("tag7", "tag5", "tag3", "tag1", "tag9", "x"));
+ RuleMetadataDto metadata = insertMetadata(organization, rule, setTags("tag2", "tag4", "tag6", "tag8", "tagA"));
+ RuleDefinitionDto rule2 = db.rules().insert(setSystemTags("tag2"));
+ indexRules();
+
+ SearchResponse result = ws.newRequest()
+ .setParam("facets", "tags")
+ .setParam("organization", organization.getKey())
+ .executeProtobuf(SearchResponse.class);
+ assertThat(result.getFacets().getFacets(0).getValuesList()).extracting(v -> v.getVal(), v -> v.getCount())
+ .containsExactly(tuple("tag2", 2L), tuple("tag1", 1L), tuple("tag3", 1L), tuple("tag4", 1L), tuple("tag5", 1L), tuple("tag6", 1L), tuple("tag7", 1L), tuple("tag8", 1L),
+ tuple("tag9", 1L), tuple("tagA", 1L));
}
@Test