Skip to content

Commit 33783a1

Browse files
authored
feat(instance-search): add sorting options for instances by created and updated date (#849)
Closes: MSEARCH-825
1 parent 2480b68 commit 33783a1

File tree

5 files changed

+149
-29
lines changed

5 files changed

+149
-29
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
* Add support for searching by instance/holdings/item electronic access relationship ID ([MSEARCH-816](https://folio-org.atlassian.net/browse/MSEARCH-816))
3535
* Normalize ISSN search ([MSEARCH-658](https://folio-org.atlassian.net/browse/MSEARCH-658))
3636
* Separate LCCN and Canceled LCCN identifiers search to lccn and canceledLccn options ([MSEARCH-1065](https://folio-org.atlassian.net/browse/MSEARCH-1065))
37+
* Add sorting options for instances by created and updated date ([MSEARCH-825](https://folio-org.atlassian.net/browse/MSEARCH-825))
3738
* **Linked Data Instance and Work**
3839
* Search by classification type/number/additionalNumber ([MSEARCH-989](https://folio-org.atlassian.net/browse/MSEARCH-989))
3940

README.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -963,21 +963,22 @@ In case where options are similar, secondary sort is used
963963

964964
##### Instance sort options
965965

966-
| Option | Type | Secondary sort | Description |
967-
|:--------------------|:---------:|:---------------|:-----------------------------------|
968-
| `title` | full text | relevancy | Sort instances by title |
969-
| `contributors` | term | relevancy | Sort instances by contributors |
970-
| `items.status.name` | term | `title` | Sort instances by status |
971-
| `item.status.name` | term | `title` | Sort instances by status |
972-
| `normalizedDate1` | term | relevancy | Sort instances by normalizedDate1 |
966+
| Option | Secondary sort | Description |
967+
|:------------------------|:---------------|:--------------------------------------|
968+
| `title` | relevancy | Sort instances by title |
969+
| `contributors` | relevancy | Sort instances by contributors |
970+
| `item.status.name` | `title` | Sort instances by status |
971+
| `normalizedDate1` | relevancy | Sort instances by normalizedDate1 |
972+
| `metadata.createdDate` | relevancy | Sort instances by created date |
973+
| `metadata.updatedDate` | relevancy | Sort instances by updated date |
973974

974975
##### Authority sort options
975976

976-
| Option | Type | Secondary sort | Description |
977-
|:--------------|:----:|:---------------|:----------------------------------------|
978-
| `headingRef` | term | relevancy | Sort authorities by Heading/Reference |
979-
| `headingType` | term | `headingRef` | Sort authorities by Type of heading |
980-
| `authRefType` | term | `headingRef` | Sort authorities by Authority/Reference |
977+
| Option | Secondary sort | Description |
978+
|:--------------|:---------------|:----------------------------------------|
979+
| `headingRef` | relevancy | Sort authorities by Heading/Reference |
980+
| `headingType` | `headingRef` | Sort authorities by Type of heading |
981+
| `authRefType` | `headingRef` | Sort authorities by Authority/Reference |
981982

982983
### Browse API
983984

src/main/resources/model/instance.json

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,15 +177,23 @@
177177
"type": "object",
178178
"properties": {
179179
"createdDate": {
180-
"searchTypes": "filter",
181-
"index": "date"
180+
"searchTypes": [ "filter", "sort" ],
181+
"index": "date",
182+
"sort": {
183+
"fieldName": "metadata.createdDate",
184+
"type": "single"
185+
}
182186
},
183187
"createdByUserId": {
184188
"index": "keyword_lowercase"
185189
},
186190
"updatedDate": {
187-
"searchTypes": "filter",
188-
"index": "date"
191+
"searchTypes": [ "filter", "sort" ],
192+
"index": "date",
193+
"sort": {
194+
"fieldName": "metadata.updatedDate",
195+
"type": "single"
196+
}
189197
},
190198
"updatedByUserId": {
191199
"index": "keyword_lowercase"

src/main/resources/swagger.api/parameters/instance-search-cql-query.yaml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,48 @@ description: |
331331
</tr>
332332
</tbody>
333333
</table>
334+
<h5 id="instance-sort-options">Instance sort options</h5>
335+
<table>
336+
<thead>
337+
<tr>
338+
<th>Option</th>
339+
<th>Secondary sort</th>
340+
<th>Description</th>
341+
</tr>
342+
</thead>
343+
<tbody>
344+
<tr>
345+
<td>title</td>
346+
<td>relevancy</td>
347+
<td>Sort instances by title</td>
348+
</tr>
349+
<tr>
350+
<td>contributors</td>
351+
<td>relevancy</td>
352+
<td>Sort instances by contributors</td>
353+
</tr>
354+
<tr>
355+
<td>item.status.name</td>
356+
<td>title</td>
357+
<td>Sort instances by status</td>
358+
</tr>
359+
<tr>
360+
<td>normalizedDate1</td>
361+
<td>relevancy</td>
362+
<td>Sort instances by normalizedDate1</td>
363+
</tr>
364+
<tr>
365+
<td>metadata.createdDate</td>
366+
<td>relevancy</td>
367+
<td>Sort instances by created date</td>
368+
</tr>
369+
<tr>
370+
<td>metadata.updatedDate</td>
371+
<td>relevancy</td>
372+
<td>Sort instances by updated date</td>
373+
</tr>
374+
</tbody>
375+
</table>
334376
<h5 id="holdings-search-options">Holdings search options</h5>
335377
<table>
336378
<thead>

src/test/java/org/folio/api/search/SortInstanceIT.java

Lines changed: 81 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.folio.search.domain.dto.Contributor;
1313
import org.folio.search.domain.dto.Dates;
1414
import org.folio.search.domain.dto.Instance;
15+
import org.folio.search.domain.dto.Metadata;
1516
import org.folio.spring.testing.type.IntegrationTest;
1617
import org.folio.support.base.BaseIntegrationTest;
1718
import org.junit.jupiter.api.AfterAll;
@@ -21,6 +22,12 @@
2122
@IntegrationTest
2223
class SortInstanceIT extends BaseIntegrationTest {
2324

25+
private static final String ID_ANIMAL_FARM = randomId();
26+
private static final String ID_ZERO_MINUS_TEN = randomId();
27+
private static final String ID_CALLING_ME_HOME = randomId();
28+
private static final String ID_WALK_IN_MY_SOUL = randomId();
29+
private static final String ID_STAR_WARS = randomId();
30+
2431
@BeforeAll
2532
static void prepare() {
2633
setUpTenant(instances());
@@ -91,6 +98,50 @@ void canSortInstancesByTitle_desc() throws Exception {
9198
.andExpect(jsonPath("instances[4].title", is("Calling Me Home")));
9299
}
93100

101+
@Test
102+
void canSortInstancesByMetadataCreatedDate_asc() throws Exception {
103+
doSearchByInstances(allRecordsSortedBy("metadata.createdDate", ASCENDING))
104+
.andExpect(jsonPath("totalRecords", is(5)))
105+
.andExpect(jsonPath("instances[0].id", is(ID_ANIMAL_FARM)))
106+
.andExpect(jsonPath("instances[1].id", is(ID_ZERO_MINUS_TEN)))
107+
.andExpect(jsonPath("instances[2].id", is(ID_CALLING_ME_HOME)))
108+
.andExpect(jsonPath("instances[3].id", is(ID_WALK_IN_MY_SOUL)))
109+
.andExpect(jsonPath("instances[4].id", is(ID_STAR_WARS)));
110+
}
111+
112+
@Test
113+
void canSortInstancesByMetadataCreatedDate_desc() throws Exception {
114+
doSearchByInstances(allRecordsSortedBy("metadata.createdDate", DESCENDING))
115+
.andExpect(jsonPath("totalRecords", is(5)))
116+
.andExpect(jsonPath("instances[0].id", is(ID_STAR_WARS)))
117+
.andExpect(jsonPath("instances[1].id", is(ID_WALK_IN_MY_SOUL)))
118+
.andExpect(jsonPath("instances[2].id", is(ID_CALLING_ME_HOME)))
119+
.andExpect(jsonPath("instances[3].id", is(ID_ZERO_MINUS_TEN)))
120+
.andExpect(jsonPath("instances[4].id", is(ID_ANIMAL_FARM)));
121+
}
122+
123+
@Test
124+
void canSortInstancesByMetadataUpdatedDate_asc() throws Exception {
125+
doSearchByInstances(allRecordsSortedBy("metadata.updatedDate", ASCENDING))
126+
.andExpect(jsonPath("totalRecords", is(5)))
127+
.andExpect(jsonPath("instances[0].id", is(ID_ANIMAL_FARM)))
128+
.andExpect(jsonPath("instances[1].id", is(ID_ZERO_MINUS_TEN)))
129+
.andExpect(jsonPath("instances[2].id", is(ID_CALLING_ME_HOME)))
130+
.andExpect(jsonPath("instances[3].id", is(ID_WALK_IN_MY_SOUL)))
131+
.andExpect(jsonPath("instances[4].id", is(ID_STAR_WARS)));
132+
}
133+
134+
@Test
135+
void canSortInstancesByMetadataUpdatedDate_desc() throws Exception {
136+
doSearchByInstances(allRecordsSortedBy("metadata.updatedDate", DESCENDING))
137+
.andExpect(jsonPath("totalRecords", is(5)))
138+
.andExpect(jsonPath("instances[0].id", is(ID_STAR_WARS)))
139+
.andExpect(jsonPath("instances[1].id", is(ID_WALK_IN_MY_SOUL)))
140+
.andExpect(jsonPath("instances[2].id", is(ID_CALLING_ME_HOME)))
141+
.andExpect(jsonPath("instances[3].id", is(ID_ZERO_MINUS_TEN)))
142+
.andExpect(jsonPath("instances[4].id", is(ID_ANIMAL_FARM)));
143+
}
144+
94145
@Test
95146
void search_negative_invalidSortOption() throws Exception {
96147
attemptSearchByInstances(allRecordsSortedBy("unknownSort", DESCENDING)).andExpect(
@@ -103,35 +154,52 @@ void search_negative_invalidSortOption() throws Exception {
103154
}
104155

105156
private static Instance[] instances() {
106-
var instances = new Instance[] {getSemanticWeb().id(randomId()).contributors(new ArrayList<>()),
107-
getSemanticWeb().id(randomId()).contributors(new ArrayList<>()),
108-
getSemanticWeb().id(randomId()).contributors(new ArrayList<>()),
109-
getSemanticWeb().id(randomId()).contributors(new ArrayList<>()),
110-
getSemanticWeb().id(randomId()).contributors(new ArrayList<>())};
111-
157+
var instances = new Instance[] {
158+
getSemanticWeb().id(ID_ANIMAL_FARM).contributors(new ArrayList<>()),
159+
getSemanticWeb().id(ID_ZERO_MINUS_TEN).contributors(new ArrayList<>()),
160+
getSemanticWeb().id(ID_CALLING_ME_HOME).contributors(new ArrayList<>()),
161+
getSemanticWeb().id(ID_WALK_IN_MY_SOUL).contributors(new ArrayList<>()),
162+
getSemanticWeb().id(ID_STAR_WARS).contributors(new ArrayList<>())
163+
};
112164
instances[0].title("Animal farm")
113165
.indexTitle("B1 Animal farm")
114166
.addContributorsItem(new Contributor().name("yyy zzz"))
115-
.setDates(getDates("1999", "2000"));
167+
.dates(getDates("1999", "2000"))
168+
.metadata(new Metadata()
169+
.createdDate("2021-01-01T10:00:00.000+00:00")
170+
.updatedDate("2021-01-15T10:00:00.000+00:00"));
116171

117172
instances[1].title("Zero Minus Ten")
118173
.indexTitle(null)
119174
.addContributorsItem(new Contributor().name("aaa bbb").primary(false))
120175
.addContributorsItem(new Contributor().name("bbb ccc").primary(true))
121-
.setDates(getDates("199u", "2000"));
176+
.dates(getDates("199u", "2000"))
177+
.metadata(new Metadata()
178+
.createdDate("2021-02-01T10:00:00.000+00:00")
179+
.updatedDate("2021-02-15T10:00:00.000+00:00"));
122180

123181
instances[2].title("Calling Me Home")
124182
.indexTitle("A1 Calling Me Home")
125183
.addContributorsItem(new Contributor().name("bcc ccc"))
126-
.setDates(getDates("2021", "2022"));
184+
.dates(getDates("2021", "2022"))
185+
.metadata(new Metadata()
186+
.createdDate("2021-03-01T10:00:00.000+00:00")
187+
.updatedDate("2021-03-15T10:00:00.000+00:00"));
127188

128189
instances[3].title("Walk in My Soul")
129190
.indexTitle(null)
130191
.addContributorsItem(new Contributor().name("1111 2222").primary(true))
131-
.setDates(getDates("2001", "2002"));
132-
133-
instances[4].title("Star Wars").indexTitle(null).addContributorsItem(new Contributor().name("Śląsk").primary(true))
134-
.setDates(getDates("19u5", "1998"));
192+
.dates(getDates("2001", "2002"))
193+
.metadata(new Metadata()
194+
.createdDate("2021-04-01T10:00:00.000+00:00")
195+
.updatedDate("2021-04-15T10:00:00.000+00:00"));
196+
197+
instances[4].title("Star Wars").indexTitle(null)
198+
.addContributorsItem(new Contributor().name("Śląsk").primary(true))
199+
.dates(getDates("19u5", "1998"))
200+
.metadata(new Metadata()
201+
.createdDate("2021-05-01T10:00:00.000+00:00")
202+
.updatedDate("2021-05-15T10:00:00.000+00:00"));
135203

136204
return instances;
137205
}

0 commit comments

Comments
 (0)