@@ -33,8 +33,7 @@ import org.springframework.data.elasticsearch.core.query.IndexQuery
33
33
import org.springframework.security.core.context.SecurityContextHolder
34
34
import org.springframework.stereotype.Service
35
35
import uk.gov.justice.hmpps.probationsearch.contactsearch.ContactSearchService.SortType
36
- import uk.gov.justice.hmpps.probationsearch.contactsearch.ContactSearchService.SortType.LAST_UPDATED_DATETIME
37
- import uk.gov.justice.hmpps.probationsearch.contactsearch.ContactSearchService.SortType.SCORE
36
+ import uk.gov.justice.hmpps.probationsearch.contactsearch.ContactSearchService.SortType.*
38
37
import uk.gov.justice.hmpps.probationsearch.services.DeliusService
39
38
import uk.gov.justice.hmpps.sqs.audit.HmppsAuditService
40
39
import java.time.Instant
@@ -111,14 +110,9 @@ class ContactSearchService(
111
110
.trackTotalHits(TrackHits .of { it.count(5000 ) })
112
111
.size(pageable.pageSize)
113
112
.from(pageable.offset.toInt())
114
- .sort { sort ->
115
- // Note: Hybrid query does not allow sorting by multiple fields including score
116
- val order = pageable.sort.singleOrNull() ? : Sort .Order .desc(SCORE .searchField)
117
- sort.field {
118
- it.field(order.property)
119
- .order(if (order.isDescending) JavaClientSortOrder .Desc else JavaClientSortOrder .Asc )
120
- }
121
- }
113
+ // Note: We're currently unable to reliably sort hybrid results until OpenSearch 2.19, so we re-sort the results later
114
+ // See https://github.com/opensearch-project/neural-search/issues/1067
115
+ .sort { sort -> sort.field { it.field(SCORE .searchField).order(JavaClientSortOrder .Desc ) } }
122
116
.highlight { highlight ->
123
117
highlight
124
118
.encoder(HighlighterEncoder .Html )
@@ -143,7 +137,17 @@ class ContactSearchService(
143
137
response.pageable.pageNumber,
144
138
response.totalElements,
145
139
response.totalPages,
146
- results,
140
+ results.sortedWith(
141
+ SortType .entries
142
+ .flatMap { type -> type.aliases.mapNotNull { alias -> pageable.sort.getOrderFor(alias)?.let { type to it } } }
143
+ .fold(Comparator { _, _ -> 0 }) { comparator, (type, order) ->
144
+ val selector = when (type) {
145
+ DATE -> { contact: ContactSearchResult -> contact.date }
146
+ else -> { contact: ContactSearchResult -> contact.score }
147
+ }
148
+ if (order.isDescending) comparator.thenByDescending(selector) else comparator.thenBy(selector)
149
+ },
150
+ ),
147
151
)
148
152
}
149
153
0 commit comments