Skip to content

Commit

Permalink
Merge pull request DSpace#10057 from toniprieto/limit-metadata-browse…
Browse files Browse the repository at this point in the history
…-facet-query

Add limit, offset, and total facet count to Solr query for the metadata browse index
  • Loading branch information
tdonohue authored Dec 18, 2024
2 parents 1449e2e + e71de8a commit 0cb85f0
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 36 deletions.
30 changes: 3 additions & 27 deletions dspace-api/src/main/java/org/dspace/browse/BrowseEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -422,9 +422,6 @@ private BrowseInfo browseByValue(BrowserScope bs)
}
}

// this is the total number of results in answer to the query
int total = getTotalResults(true);

// set the ordering field (there is only one option)
dao.setOrderField("sort_value");

Expand All @@ -444,6 +441,9 @@ private BrowseInfo browseByValue(BrowserScope bs)
dao.setOffset(offset);
dao.setLimit(scope.getResultsPerPage());

// this is the total number of results in answer to the query
int total = getTotalResults(true);

// Holder for the results
List<String[]> results = null;

Expand Down Expand Up @@ -680,33 +680,9 @@ private int getTotalResults(boolean distinct)
// tell the browse query whether we are distinct
dao.setDistinct(distinct);

// ensure that the select is set to "*"
String[] select = {"*"};
dao.setCountValues(select);

// FIXME: it would be nice to have a good way of doing this in the DAO
// now reset all of the fields that we don't want to have constraining
// our count, storing them locally to reinstate later
String focusField = dao.getJumpToField();
String focusValue = dao.getJumpToValue();
int limit = dao.getLimit();
int offset = dao.getOffset();

dao.setJumpToField(null);
dao.setJumpToValue(null);
dao.setLimit(-1);
dao.setOffset(-1);

// perform the query and get the result
int count = dao.doCountQuery();

// now put back the values we removed for this method
dao.setJumpToField(focusField);
dao.setJumpToValue(focusValue);
dao.setLimit(limit);
dao.setOffset(offset);
dao.setCountValues(null);

log.debug(LogHelper.getHeader(context, "get_total_results_return", "return=" + count));

return count;
Expand Down
32 changes: 24 additions & 8 deletions dspace-api/src/main/java/org/dspace/browse/SolrBrowseDAO.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import java.util.Comparator;
import java.util.List;

import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.apache.solr.client.solrj.util.ClientUtils;
Expand Down Expand Up @@ -180,18 +182,33 @@ private DiscoverResult getSolrResponse() throws BrowseException {
addDefaultFilterQueries(query);
if (distinct) {
DiscoverFacetField dff;

// To get the number of distinct values we use the next "json.facet" query param
// {"entries_count": {"type":"terms","field": "<fieldName>_filter", "limit":0, "numBuckets":true}}"
ObjectNode jsonFacet = JsonNodeFactory.instance.objectNode();
ObjectNode entriesCount = JsonNodeFactory.instance.objectNode();
entriesCount.put("type", "terms");
entriesCount.put("field", facetField + "_filter");
entriesCount.put("limit", 0);
entriesCount.put("numBuckets", true);
jsonFacet.set("entries_count", entriesCount);

if (StringUtils.isNotBlank(startsWith)) {
dff = new DiscoverFacetField(facetField,
DiscoveryConfigurationParameters.TYPE_TEXT, -1,
DiscoveryConfigurationParameters.SORT.VALUE, startsWith);
DiscoveryConfigurationParameters.TYPE_TEXT, limit,
DiscoveryConfigurationParameters.SORT.VALUE, startsWith, offset);

// Add the prefix to the json facet query
entriesCount.put("prefix", startsWith);
} else {
dff = new DiscoverFacetField(facetField,
DiscoveryConfigurationParameters.TYPE_TEXT, -1,
DiscoveryConfigurationParameters.SORT.VALUE);
DiscoveryConfigurationParameters.TYPE_TEXT, limit,
DiscoveryConfigurationParameters.SORT.VALUE, offset);
}
query.addFacetField(dff);
query.setFacetMinCount(1);
query.setMaxResults(0);
query.addProperty("json.facet", jsonFacet.toString());
} else {
query.setMaxResults(limit/* > 0 ? limit : 20*/);
if (offset > 0) {
Expand Down Expand Up @@ -248,8 +265,7 @@ public int doCountQuery() throws BrowseException {
DiscoverResult resp = getSolrResponse();
int count = 0;
if (distinct) {
List<FacetResult> facetResults = resp.getFacetResult(facetField);
count = facetResults.size();
count = (int) resp.getTotalEntries();
} else {
// we need to cast to int to respect the BrowseDAO contract...
count = (int) resp.getTotalSearchResults();
Expand All @@ -266,8 +282,8 @@ public List doValueQuery() throws BrowseException {
DiscoverResult resp = getSolrResponse();
List<FacetResult> facet = resp.getFacetResult(facetField);
int count = doCountQuery();
int start = offset > 0 ? offset : 0;
int max = limit > 0 ? limit : count; //if negative, return everything
int start = 0;
int max = facet.size();
List<String[]> result = new ArrayList<>();
if (ascending) {
for (int i = start; i < (start + max) && i < count; i++) {
Expand Down
11 changes: 11 additions & 0 deletions dspace-api/src/main/java/org/dspace/discovery/DiscoverResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ public class DiscoverResult {
private List<IndexableObject> indexableObjects;
private Map<String, List<FacetResult>> facetResults;

// Total count of facet entries calculated for a metadata browsing query
private long totalEntries;

/**
* A map that contains all the documents sougth after, the key is a string representation of the Indexable Object
*/
Expand Down Expand Up @@ -64,6 +67,14 @@ public void setTotalSearchResults(long totalSearchResults) {
this.totalSearchResults = totalSearchResults;
}

public long getTotalEntries() {
return totalEntries;
}

public void setTotalEntries(long totalEntries) {
this.totalEntries = totalEntries;
}

public int getStart() {
return start;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1055,6 +1055,8 @@ protected DiscoverResult retrieveResult(Context context, DiscoverQuery query)
}
//Resolve our facet field values
resolveFacetFields(context, query, result, skipLoadingResponse, solrQueryResponse);
//Add total entries count for metadata browsing
resolveEntriesCount(result, solrQueryResponse);
}
// If any stale entries are found in the current page of results,
// we remove those stale entries and rerun the same query again.
Expand All @@ -1080,7 +1082,39 @@ protected DiscoverResult retrieveResult(Context context, DiscoverQuery query)
return result;
}


/**
* Stores the total count of entries for metadata index browsing. The count is calculated by the
* <code>json.facet</code> parameter with the following value:
*
* <pre><code>
* {
* "entries_count": {
* "type": "terms",
* "field": "facetNameField_filter",
* "limit": 0,
* "prefix": "prefix_value",
* "numBuckets": true
* }
* }
* </code></pre>
*
* This value is returned in the <code>facets</code> field of the Solr response.
*
* @param result DiscoverResult object where the total entries count will be stored
* @param solrQueryResponse QueryResponse object containing the solr response
*/
private void resolveEntriesCount(DiscoverResult result, QueryResponse solrQueryResponse) {

Object facetsObj = solrQueryResponse.getResponse().get("facets");
if (facetsObj instanceof NamedList) {
NamedList<Object> facets = (NamedList<Object>) facetsObj;
Object bucketsInfoObj = facets.get("entries_count");
if (bucketsInfoObj instanceof NamedList) {
NamedList<Object> bucketsInfo = (NamedList<Object>) bucketsInfoObj;
result.setTotalEntries((int) bucketsInfo.get("numBuckets"));
}
}
}

private void resolveFacetFields(Context context, DiscoverQuery query, DiscoverResult result,
boolean skipLoadingResponse, QueryResponse solrQueryResponse) throws SQLException {
Expand Down

0 comments on commit 0cb85f0

Please sign in to comment.