Skip to content

Commit

Permalink
Merge pull request #8857 from buithaihai/DS-8837
Browse files Browse the repository at this point in the history
Fix: default sort option for discovery
  • Loading branch information
tdonohue committed Jun 2, 2023
2 parents 44d038c + 3928365 commit 9735020
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 2 deletions.
Expand Up @@ -9,6 +9,7 @@

import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
Expand All @@ -22,6 +23,11 @@ public class DiscoverySortConfiguration {

private List<DiscoverySortFieldConfiguration> sortFields = new ArrayList<DiscoverySortFieldConfiguration>();

/**
* Default sort configuration to use when needed
*/
@Nullable private DiscoverySortFieldConfiguration defaultSortField;

public List<DiscoverySortFieldConfiguration> getSortFields() {
return sortFields;
}
Expand All @@ -30,6 +36,14 @@ public void setSortFields(List<DiscoverySortFieldConfiguration> sortFields) {
this.sortFields = sortFields;
}

public DiscoverySortFieldConfiguration getDefaultSortField() {
return defaultSortField;
}

public void setDefaultSortField(DiscoverySortFieldConfiguration configuration) {
this.defaultSortField = configuration;
}

public DiscoverySortFieldConfiguration getSortFieldConfiguration(String sortField) {
if (StringUtils.isBlank(sortField)) {
return null;
Expand Down
Expand Up @@ -332,7 +332,9 @@ private boolean isConfigured(String sortBy, DiscoverySortConfiguration searchSor
}

private String getDefaultSortDirection(DiscoverySortConfiguration searchSortConfiguration, String sortOrder) {
if (Objects.nonNull(searchSortConfiguration.getSortFields()) &&
if (searchSortConfiguration.getDefaultSortField() != null) {
sortOrder = searchSortConfiguration.getDefaultSortField().getDefaultSortOrder().name();
} else if (Objects.nonNull(searchSortConfiguration.getSortFields()) &&
!searchSortConfiguration.getSortFields().isEmpty()) {
sortOrder = searchSortConfiguration.getSortFields().get(0).getDefaultSortOrder().name();
}
Expand All @@ -342,7 +344,9 @@ private String getDefaultSortDirection(DiscoverySortConfiguration searchSortConf
private String getDefaultSortField(DiscoverySortConfiguration searchSortConfiguration) {
String sortBy;// Attempt to find the default one, if none found we use SCORE
sortBy = "score";
if (Objects.nonNull(searchSortConfiguration.getSortFields()) &&
if (searchSortConfiguration.getDefaultSortField() != null) {
sortBy = searchSortConfiguration.getDefaultSortField().getMetadataField();
} else if (Objects.nonNull(searchSortConfiguration.getSortFields()) &&
!searchSortConfiguration.getSortFields().isEmpty()) {
DiscoverySortFieldConfiguration defaultSort = searchSortConfiguration.getSortFields().get(0);
if (StringUtils.isBlank(defaultSort.getMetadataField())) {
Expand Down
64 changes: 64 additions & 0 deletions dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java
Expand Up @@ -8,13 +8,16 @@
package org.dspace.discovery;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;

import org.dspace.AbstractIntegrationTestWithDatabase;
Expand All @@ -24,6 +27,7 @@
import org.dspace.builder.ClaimedTaskBuilder;
import org.dspace.builder.CollectionBuilder;
import org.dspace.builder.CommunityBuilder;
import org.dspace.builder.EPersonBuilder;
import org.dspace.builder.ItemBuilder;
import org.dspace.builder.PoolTaskBuilder;
import org.dspace.builder.WorkflowItemBuilder;
Expand All @@ -39,6 +43,8 @@
import org.dspace.content.service.CollectionService;
import org.dspace.content.service.ItemService;
import org.dspace.content.service.WorkspaceItemService;
import org.dspace.discovery.configuration.DiscoveryConfiguration;
import org.dspace.discovery.configuration.DiscoverySortFieldConfiguration;
import org.dspace.discovery.indexobject.IndexableClaimedTask;
import org.dspace.discovery.indexobject.IndexableCollection;
import org.dspace.discovery.indexobject.IndexableItem;
Expand Down Expand Up @@ -731,6 +737,64 @@ public void iteratorSearchServiceTest() throws SearchServiceException {
}
}

/**
* Test designed to check if default sort option for Discovery is working, using <code>workspace</code>
* DiscoveryConfiguration <br/>
* <b>Note</b>: this test will be skipped if <code>workspace</code> do not have a default sort option set and of
* metadataType <code>dc_date_accessioned</code> or <code>lastModified</code>
* @throws SearchServiceException
*/
@Test
public void searchWithDefaultSortServiceTest() throws SearchServiceException {

DiscoveryConfiguration workspaceConf = SearchUtils.getDiscoveryConfiguration("workspace", null);
// Skip if no default sort option set for workspaceConf
if (workspaceConf.getSearchSortConfiguration().getDefaultSortField() == null) {
return;
}

DiscoverySortFieldConfiguration defaultSortField =
workspaceConf.getSearchSortConfiguration().getDefaultSortField();

// Populate the testing objects: create items in eperson's workspace and perform search in it
int numberItems = 10;
context.turnOffAuthorisationSystem();
EPerson submitter = EPersonBuilder.createEPerson(context).withEmail("submitter@example.org").build();
context.setCurrentUser(submitter);
Community community = CommunityBuilder.createCommunity(context).build();
Collection collection = CollectionBuilder.createCollection(context, community).build();
for (int i = 0; i < numberItems; i++) {
ItemBuilder.createItem(context, collection)
.withTitle("item " + i)
.build();
}
context.restoreAuthSystemState();

// Build query with default parameters (except for workspaceConf)
DiscoverQuery discoverQuery = SearchUtils.getQueryBuilder()
.buildQuery(context, new IndexableCollection(collection), workspaceConf,"",null,"Item",null,null,
null,null);

DiscoverResult result = searchService.search(context, discoverQuery);

/*
// code example for testing against sort by dc_date_accessioned
LinkedList<String> dc_date_accesioneds = result.getIndexableObjects().stream()
.map(o -> ((Item) o.getIndexedObject()).getMetadata())
.map(l -> l.stream().filter(m -> m.getMetadataField().toString().equals("dc_date_accessioned"))
.map(m -> m.getValue()).findFirst().orElse("")
)
.collect(Collectors.toCollection(LinkedList::new));
}*/
LinkedList<String> lastModifieds = result.getIndexableObjects().stream()
.map(o -> ((Item) o.getIndexedObject()).getLastModified().toString())
.collect(Collectors.toCollection(LinkedList::new));
assertFalse(lastModifieds.isEmpty());
for (int i = 1; i < lastModifieds.size() - 1; i++) {
assertTrue(lastModifieds.get(i).compareTo(lastModifieds.get(i + 1)) >= 0);
}
}

private void assertSearchQuery(String resourceType, int size) throws SearchServiceException {
assertSearchQuery(resourceType, size, size, 0, -1);
}
Expand Down
Expand Up @@ -80,6 +80,15 @@ private void addSortOptions(SearchConfigurationRest searchConfigurationRest,
sortOption.setSortOrder(discoverySearchSortConfiguration.getDefaultSortOrder().name());
searchConfigurationRest.addSortOption(sortOption);
}

DiscoverySortFieldConfiguration defaultSortField = searchSortConfiguration.getDefaultSortField();
if (defaultSortField != null) {
SearchConfigurationRest.SortOption sortOption = new SearchConfigurationRest.SortOption();
sortOption.setName(defaultSortField.getMetadataField());
sortOption.setActualName(defaultSortField.getType());
sortOption.setSortOrder(defaultSortField.getDefaultSortOrder().name());
searchConfigurationRest.setDefaultSortOption(sortOption);
}
}

}
Expand Down
Expand Up @@ -31,6 +31,8 @@ public class SearchConfigurationRest extends BaseObjectRest<String> {
private List<Filter> filters = new LinkedList<>();
private List<SortOption> sortOptions = new LinkedList<>();

private SortOption defaultSortOption;

public String getCategory() {
return CATEGORY;
}
Expand Down Expand Up @@ -75,6 +77,14 @@ public List<SortOption> getSortOptions() {
return sortOptions;
}

public SortOption getDefaultSortOption() {
return defaultSortOption;
}

public void setDefaultSortOption(SortOption defaultSortOption) {
this.defaultSortOption = defaultSortOption;
}

@Override
public boolean equals(Object object) {
return (object instanceof SearchConfigurationRest &&
Expand Down
Expand Up @@ -115,6 +115,8 @@ public void setUp() throws Exception {

sortConfiguration.setSortFields(listSortField);

sortConfiguration.setDefaultSortField(defaultSort);

discoveryConfiguration.setSearchSortConfiguration(sortConfiguration);

DiscoverySearchFilterFacet subjectFacet = new DiscoverySearchFilterFacet();
Expand Down Expand Up @@ -167,6 +169,16 @@ public void testSortByScore() throws Exception {
page.getOffset(), "SCORE", "ASC");
}

@Test
public void testSortByDefaultSortField() throws Exception {
page = PageRequest.of(2, 10);
restQueryBuilder.buildQuery(context, null, discoveryConfiguration, null, null, emptyList(), page);

verify(discoverQueryBuilder, times(1))
.buildQuery(context, null, discoveryConfiguration, null, emptyList(), emptyList(),
page.getPageSize(), page.getOffset(), null, null);
}

@Test(expected = DSpaceBadRequestException.class)
public void testCatchIllegalArgumentException() throws Exception {
when(discoverQueryBuilder.buildQuery(any(), any(), any(), any(), any(), anyList(), any(), any(), any(),
Expand Down
6 changes: 6 additions & 0 deletions dspace/config/spring/api/discovery.xml
Expand Up @@ -865,8 +865,11 @@
<!--The sort filters for the discovery search-->
<property name="searchSortConfiguration">
<bean class="org.dspace.discovery.configuration.DiscoverySortConfiguration">
<!--The default sort filter to use for the initial workspace loading-->
<property name="defaultSortField" ref="sortLastModified" />
<property name="sortFields">
<list>
<ref bean="sortLastModified" />
<ref bean="sortScore" />
<ref bean="sortTitle" />
<ref bean="sortDateIssued" />
Expand Down Expand Up @@ -938,6 +941,8 @@
<!--The sort filters for the discovery search-->
<property name="searchSortConfiguration">
<bean class="org.dspace.discovery.configuration.DiscoverySortConfiguration">
<!--The default sort filter to use for the initial workspace loading-->
<property name="defaultSortField" ref="sortLastModified" />
<property name="sortFields">
<list>
<ref bean="sortLastModified" />
Expand Down Expand Up @@ -1015,6 +1020,7 @@
<bean class="org.dspace.discovery.configuration.DiscoverySortConfiguration">
<property name="sortFields">
<list>
<ref bean="sortLastModified" />
<ref bean="sortScore" />
<ref bean="sortTitle" />
<ref bean="sortDateIssued" />
Expand Down
1 change: 1 addition & 0 deletions dspace/solr/search/conf/schema.xml
Expand Up @@ -283,6 +283,7 @@
<!-- used by the DSpace Discovery Solr Indexer to track the last time a document was indexed -->
<field name="SolrIndexer.lastIndexed" type="date" indexed="true" stored="true" default="NOW" multiValued="false" omitNorms="true" />
<field name="lastModified" type="date" indexed="true" stored="true" default="NOW" multiValued="false" omitNorms="true" />
<copyField source="lastModified" dest="lastModified_dt" />

<!-- used to filter out items that are older versions of another item -->
<field name="latestVersion" type="boolean" indexed="true" stored="true" default="true" multiValued="false" omitNorms="true"/>
Expand Down

0 comments on commit 9735020

Please sign in to comment.