Skip to content

Commit

Permalink
include total_count_per_object_type in search response
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenwinship committed Dec 10, 2024
1 parent 6e3a250 commit 2dd997c
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The JSON payload of the search endpoint has been extended to include total_count_per_object_type for types: dataverse, dataset, and files when the search parameter "&show_type_counts=true" is passed in.
11 changes: 11 additions & 0 deletions src/main/java/edu/harvard/iq/dataverse/api/Search.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
Expand Down Expand Up @@ -73,6 +74,7 @@ public Response search(
@QueryParam("metadata_fields") List<String> metadataFields,
@QueryParam("geo_point") String geoPointRequested,
@QueryParam("geo_radius") String geoRadiusRequested,
@QueryParam("show_type_counts") boolean showTypeCounts,
@Context HttpServletResponse response
) {

Expand Down Expand Up @@ -172,9 +174,13 @@ public Response search(
return error(Response.Status.INTERNAL_SERVER_ERROR, message);
}

Map<String, Integer> itemCountByType = new HashMap<>();
JsonArrayBuilder itemsArrayBuilder = Json.createArrayBuilder();
List<SolrSearchResult> solrSearchResults = solrQueryResponse.getSolrSearchResults();
for (SolrSearchResult solrSearchResult : solrSearchResults) {
if (showTypeCounts) {
itemCountByType.merge(solrSearchResult.getType(), 1, Integer::sum);
}
itemsArrayBuilder.add(solrSearchResult.json(showRelevance, showEntityIds, showApiUrls, metadataFields));
}

Expand Down Expand Up @@ -210,6 +216,11 @@ public Response search(
}

value.add("count_in_response", solrSearchResults.size());
if (showTypeCounts && !itemCountByType.isEmpty()) {
JsonObjectBuilder objectTypeCounts = Json.createObjectBuilder();
itemCountByType.forEach((k,v) -> objectTypeCounts.add(k,v));
value.add("total_count_per_object_type", objectTypeCounts);
}
/**
* @todo Returning the fq might be useful as a troubleshooting aid
* but we don't want to expose the raw dataverse database ids in
Expand Down
61 changes: 61 additions & 0 deletions src/test/java/edu/harvard/iq/dataverse/api/SearchIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -1347,4 +1347,65 @@ public void testSearchFilesAndUrlImages() {
.body("data.items[0].url", CoreMatchers.containsString("/datafile/"))
.body("data.items[0]", CoreMatchers.not(CoreMatchers.hasItem("image_url")));
}

@Test
public void testShowTypeCounts() {
//Create 1 user and 1 Dataverse/Collection
Response createUser = UtilIT.createRandomUser();
String username = UtilIT.getUsernameFromResponse(createUser);
String apiToken = UtilIT.getApiTokenFromResponse(createUser);
String affiliation = "testAffiliation";

// test total_count_per_object_type is not included because the results are empty
Response searchResp = UtilIT.search(username, apiToken, "&show_type_counts=true");
searchResp.then().assertThat()
.statusCode(OK.getStatusCode())
.body("data.total_count_per_object_type", CoreMatchers.equalTo(null));

Response createDataverseResponse = UtilIT.createRandomDataverse(apiToken, affiliation);
assertEquals(201, createDataverseResponse.getStatusCode());
String dataverseAlias = UtilIT.getAliasFromResponse(createDataverseResponse);

// create 3 Datasets, each with 2 Datafiles
for (int i = 0; i < 3; i++) {
Response createDatasetResponse = UtilIT.createRandomDatasetViaNativeApi(dataverseAlias, apiToken);
createDatasetResponse.then().assertThat()
.statusCode(CREATED.getStatusCode());
String datasetId = UtilIT.getDatasetIdFromResponse(createDatasetResponse).toString();

// putting the dataverseAlias in the description of each file so the search q={dataverseAlias} will return dataverse, dataset, and files for this test only
String jsonAsString = "{\"description\":\"" + dataverseAlias + "\",\"directoryLabel\":\"data/subdir1\",\"categories\":[\"Data\"], \"restrict\":\"false\" }";

String pathToFile = "src/main/webapp/resources/images/dataverseproject.png";
Response uploadImage = UtilIT.uploadFileViaNative(datasetId, pathToFile, jsonAsString, apiToken);
uploadImage.then().assertThat()
.statusCode(200);
pathToFile = "src/main/webapp/resources/js/mydata.js";
Response uploadFile = UtilIT.uploadFileViaNative(datasetId, pathToFile, jsonAsString, apiToken);
uploadFile.then().assertThat()
.statusCode(200);

// This call forces a wait for dataset indexing to finish and gives time for file uploads to complete
UtilIT.search("id:dataset_" + datasetId, apiToken);
}

// Test Search without show_type_counts
searchResp = UtilIT.search(dataverseAlias, apiToken);
searchResp.then().assertThat()
.statusCode(OK.getStatusCode())
.body("data.total_count_per_object_type", CoreMatchers.equalTo(null));
// Test Search with show_type_counts = FALSE
searchResp = UtilIT.search(dataverseAlias, apiToken, "&show_type_counts=false");
searchResp.then().assertThat()
.statusCode(OK.getStatusCode())
.body("data.total_count_per_object_type", CoreMatchers.equalTo(null));
// Test Search with show_type_counts = TRUE
searchResp = UtilIT.search(dataverseAlias, apiToken, "&show_type_counts=true");
searchResp.prettyPrint();
searchResp.then().assertThat()
.statusCode(OK.getStatusCode())
.body("data.total_count_per_object_type.dataverses", CoreMatchers.is(1))
.body("data.total_count_per_object_type.datasets", CoreMatchers.is(3))
.body("data.total_count_per_object_type.files", CoreMatchers.is(6));
}
}

0 comments on commit 2dd997c

Please sign in to comment.