public SearchIdResult<String> search(ComponentQuery query, SearchOptions searchOptions) {
SearchSourceBuilder source = new SearchSourceBuilder()
.fetchSource(false)
+ .trackTotalHits(true)
.from(searchOptions.getOffset())
.size(searchOptions.getLimit());
configureQuery(sourceBuilder, filterComputer);
configureTopFilters(sourceBuilder, filterComputer);
- sourceBuilder.fetchSource(false);
+ sourceBuilder.fetchSource(false)
+ .trackTotalHits(true);
return client.search(requestBuilder);
}
public SearchIdResult<String> search(ProjectMeasuresQuery query, SearchOptions searchOptions) {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
.fetchSource(false)
+ .trackTotalHits(true)
.from(searchOptions.getOffset())
.size(searchOptions.getLimit());
import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentTesting;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.server.es.EsTester;
import org.sonar.server.es.SearchIdResult;
import static java.util.Collections.singleton;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.server.component.index.ComponentIndexDefinition.TYPE_COMPONENT;
public class ComponentIndexSearchTest {
@Rule
assertThat(result.getUuids()).containsExactlyInAnyOrder(projects.get(3).uuid(), projects.get(4).uuid(), projects.get(5).uuid());
}
+ @Test
+ public void returns_correct_total_number_if_default_index_window_exceeded() {
+ userSession.logIn().setRoot();
+
+ index(IntStream.range(0, 12_000)
+ .mapToObj(i -> newDoc(ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization())))
+ .toArray(ComponentDoc[]::new));
+
+ SearchIdResult<String> result = underTest.search(ComponentQuery.builder().build(), new SearchOptions().setPage(2, 3));
+ assertThat(result.getTotal()).isEqualTo(12_000);
+ }
+
@Test
public void filter_unauthorized_components() {
ComponentDto unauthorizedProject = db.components().insertPrivateProject();
indexer.indexAll();
Arrays.stream(components).forEach(c -> authorizationIndexerTester.allowOnlyAnyone(c));
}
+
+ private void index(ComponentDoc... componentDocs) {
+ es.putDocuments(TYPE_COMPONENT.getMainType(), componentDocs);
+ }
+
+ private ComponentDoc newDoc(ComponentDto componentDoc) {
+ return new ComponentDoc()
+ .setId(componentDoc.uuid())
+ .setKey(componentDoc.getKey())
+ .setName(componentDoc.name())
+ .setProjectUuid(componentDoc.projectUuid())
+ .setOrganization(componentDoc.getOrganizationUuid())
+ .setQualifier(componentDoc.qualifier());
+ }
}
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.apache.lucene.search.TotalHits;
+import org.apache.lucene.search.TotalHits.Relation;
import org.assertj.core.groups.Tuple;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit;
assertThat(result.getHits().getHits()).hasSize(SearchOptions.MAX_PAGE_SIZE);
}
+ // SONAR-14224
+ @Test
+ public void search_exceeding_default_index_max_window() {
+ ComponentDto project = newPrivateProjectDto(newOrganizationDto());
+ ComponentDto file = newFileDto(project, null);
+ List<IssueDoc> issues = new ArrayList<>();
+ for (int i = 0; i < 11_000; i++) {
+ String key = "I" + i;
+ issues.add(newDoc(key, file));
+ }
+ indexIssues(issues.toArray(new IssueDoc[] {}));
+
+ IssueQuery.Builder query = IssueQuery.builder();
+ SearchResponse result = underTest.search(query.build(), new SearchOptions().setLimit(500));
+ assertThat(result.getHits().getHits()).hasSize(SearchOptions.MAX_PAGE_SIZE);
+ assertThat(result.getHits().getTotalHits().value).isEqualTo(11_000L);
+ assertThat(result.getHits().getTotalHits().relation).isEqualTo(Relation.EQUAL_TO);
+ }
+
@Test
public void authorized_issues_on_groups() {
OrganizationDto org = newOrganizationDto();
APP1, APP2, APP3);
}
+ @Test
+ public void return_correct_number_of_total_if_exceeds_index_max_results() {
+ index(IntStream.range(0, 12_000)
+ .mapToObj(operand -> newDoc(ComponentTesting.newPrivateProjectDto(ORG)))
+ .toArray(ProjectMeasuresDoc[]::new));
+
+ ProjectMeasuresQuery query = new ProjectMeasuresQuery();
+ SearchIdResult<String> result = underTest.search(query, new SearchOptions());
+ assertThat(result.getTotal()).isEqualTo(12_000);
+ }
+
@Test
public void return_only_projects_and_applications_authorized_for_user() {
indexForUser(USER1, newDoc(PROJECT1), newDoc(PROJECT2),