Skip to content

Commit 2bdf47a

Browse files
committed
feat: add "relevance" to event and course search ordering options
TH-1442. Add "relevance" as a new oredring option in events and courses search. It is using "-rank" as sort-parameter value, which means descending "rank", which is also the default sort-parameter in LinkedEvents, when a full text search -parameter is used. Rank sorting option and filter scoring system is effective only when using `x_full_text` -parameter. Rank should not be explicitly set, but left empty instead, when wanted to be affective. The rank sorting needs a mandatory secondary order field and scoring annotation to queryset, which are only activated when `x_full_text` -parameter is used and sort-parameter is left empty. Ref. [LINK-2422](https://helsinkisolutionoffice.atlassian.net/browse/LINK-2422)
1 parent cf2beb2 commit 2bdf47a

6 files changed

Lines changed: 78 additions & 11 deletions

File tree

apps/events-helsinki/src/domain/search/eventSearch/utils.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import type {
33
AppLanguage,
44
Meta,
55
QueryEventListArgs,
6-
EVENT_SORT_OPTIONS,
76
KeywordOnClickHandlerType,
87
Venue,
98
} from '@events-helsinki/components';
@@ -16,6 +15,7 @@ import {
1615
scrollToTop,
1716
CITY_OF_HELSINKI_LINKED_EVENTS_ORGANIZATION_ID,
1817
EVENT_SEARCH_FILTERS,
18+
EVENT_SORT_OPTIONS,
1919
} from '@events-helsinki/components';
2020
import {
2121
addDays,
@@ -262,7 +262,12 @@ export const getEventSearchVariables = ({
262262
location: places.sort((a, b) => a.localeCompare(b)),
263263
pageSize,
264264
publisher,
265-
sort: sortOrder,
265+
/**
266+
* As per LinkedEvents requirements (see LINK-2422; https://helsinkisolutionoffice.atlassian.net/browse/LINK-2422),
267+
* relevance sorting (rank) is activated by providing an *empty string* as the sort parameter when
268+
* `x_full_text` is used, not the literal '-rank' value.
269+
*/
270+
sort: sortOrder === EVENT_SORT_OPTIONS.RANK_DESC ? '' : sortOrder,
266271
start,
267272
startsAfter,
268273
superEventType,

apps/hobbies-helsinki/src/domain/search/eventSearch/utils.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ import {
77
scrollToTop,
88
EVENT_SEARCH_FILTERS,
99
CITY_OF_HELSINKI_LINKED_EVENTS_ORGANIZATION_ID,
10+
EVENT_SORT_OPTIONS,
1011
} from '@events-helsinki/components';
1112
import type {
1213
AppLanguage,
1314
Meta,
1415
QueryEventListArgs,
1516
EventFields,
16-
EVENT_SORT_OPTIONS,
1717
KeywordOnClickHandlerType,
1818
Venue,
1919
} from '@events-helsinki/components';
@@ -247,7 +247,12 @@ export const getEventSearchVariables = ({
247247
location: places.sort((a, b) => a.localeCompare(b)),
248248
pageSize,
249249
publisher,
250-
sort: sortOrder,
250+
/**
251+
* As per LinkedEvents requirements (see LINK-2422; https://helsinkisolutionoffice.atlassian.net/browse/LINK-2422),
252+
* relevance sorting (rank) is activated by providing an *empty string* as the sort parameter when
253+
* `x_full_text` is used, not the literal '-rank' value.
254+
*/
255+
sort: sortOrder === EVENT_SORT_OPTIONS.RANK_DESC ? '' : sortOrder,
251256
start,
252257
startsAfter,
253258
superEventType,

apps/sports-helsinki/src/domain/search/combinedSearch/adapters/EventSearchAdapter.ts

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import { CITY_OF_HELSINKI_LINKED_EVENTS_ORGANIZATION_ID } from '@events-helsinki/components';
1+
import {
2+
CITY_OF_HELSINKI_LINKED_EVENTS_ORGANIZATION_ID,
3+
EVENT_SORT_OPTIONS,
4+
} from '@events-helsinki/components';
25
import { EventTypeId } from '@events-helsinki/components/types';
36
import {
47
SPORT_COURSES_KEYWORDS,
@@ -56,10 +59,11 @@ class EventSearchAdapter implements CombinedSearchAdapter<EventSearchParams> {
5659
this.keywordOrSet1 = SPORT_COURSES_KEYWORDS;
5760
this.keywordOrSet2 = this.getSportsKeywords(input);
5861
this.keywordOrSet3 = this.getTargetGroupKeywords(input);
59-
this.sort =
60-
(eventType === EventTypeId.General
61-
? input.eventOrderBy
62-
: input.courseOrderBy) ?? initialEventSearchAdapterValues.sort;
62+
this.sort = this.getSortingValue(
63+
eventType,
64+
input.eventOrderBy,
65+
input.courseOrderBy
66+
);
6367
this.publisher =
6468
input.organization ?? initialEventSearchAdapterValues.publisher;
6569
this.publisherAncestor = input.helsinkiOnly
@@ -68,6 +72,38 @@ class EventSearchAdapter implements CombinedSearchAdapter<EventSearchParams> {
6872
this.superEvent = this.getSuperEvent(eventType);
6973
}
7074

75+
/**
76+
* Determines the correct sort parameter value for an API request.
77+
*
78+
* This function selects the appropriate sort order (`eventOrderBy` or `courseOrderBy`)
79+
* based on the `eventType`. It also implements special handling for
80+
* `EVENT_SORT_OPTIONS.RANK_DESC`.
81+
*
82+
* As per LinkedEvents API requirements (see LINK-2422), relevance sorting (rank)
83+
* is activated by providing an *empty string* as the sort parameter when
84+
* `x_full_text` is used, not the literal '-rank' value. This function
85+
* performs that conversion.
86+
*
87+
* @param {EventTypeId} eventType The type of event, used to decide whether to use `eventOrderBy` or `courseOrderBy`.
88+
* @param {EventSearchParams['sort']} [eventOrderBy] The sort value to use if `eventType` is `EventTypeId.General`.
89+
* @param {EventSearchParams['sort']} [courseOrderBy] The sort value to use if `eventType` is `EventTypeId.Course`.
90+
* @returns {string} The finalized sort parameter string. Returns an empty string (`''`)
91+
* if the determined sort value is `EVENT_SORT_OPTIONS.RANK_DESC`,
92+
* otherwise returns the selected or default sort value.
93+
*/
94+
public getSortingValue(
95+
eventType: EventTypeId,
96+
eventOrderBy?: EventSearchParams['sort'],
97+
courseOrderBy?: EventSearchParams['sort']
98+
): string {
99+
const sortValue =
100+
(eventType === EventTypeId.General ? eventOrderBy : courseOrderBy) ??
101+
initialEventSearchAdapterValues.sort;
102+
103+
// RANK_DESC needs to be handled as an empty string.
104+
return sortValue === EVENT_SORT_OPTIONS.RANK_DESC ? '' : sortValue;
105+
}
106+
71107
/**
72108
* If the search is for Courses,
73109
* the superEvent should be set to 'none' -

apps/sports-helsinki/src/domain/search/eventSearch/utils.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type {
22
AppLanguage,
3-
EVENT_SORT_OPTIONS,
43
EventFields,
54
FilterType,
65
KeywordOnClickHandlerType,
@@ -22,6 +21,7 @@ import {
2221
isEventFields,
2322
isVenue,
2423
scrollToTop,
24+
EVENT_SORT_OPTIONS,
2525
} from '@events-helsinki/components';
2626
import {
2727
addDays,
@@ -244,7 +244,12 @@ export const getEventSearchVariables = ({
244244
pageSize,
245245
publisher,
246246
publisherAncestor: null,
247-
sort: sortOrder,
247+
/**
248+
* As per LinkedEvents requirements (see LINK-2422; https://helsinkisolutionoffice.atlassian.net/browse/LINK-2422),
249+
* relevance sorting (rank) is activated by providing an *empty string* as the sort parameter when
250+
* `x_full_text` is used, not the literal '-rank' value.
251+
*/
252+
sort: sortOrder === EVENT_SORT_OPTIONS.RANK_DESC ? '' : sortOrder,
248253
start,
249254
superEventType,
250255
superEvent,

packages/components/src/components/orderBySelect/EventsOrderBySelect.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ const EventsOrderBySelect: React.FC<{
2525
text: t('search:orderBy.endTime'),
2626
value: EVENT_SORT_OPTIONS.END_TIME,
2727
},
28+
{
29+
text: t('search:orderBy.relevance'),
30+
value: EVENT_SORT_OPTIONS.RANK_DESC,
31+
},
2832
{
2933
text: t('search:orderBy.lastModifiedTime'),
3034
value: EVENT_SORT_OPTIONS.LAST_MODIFIED_TIME_DESC,

packages/components/src/constants/event-constants.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,18 @@ export enum EVENT_SORT_OPTIONS {
2727
LAST_MODIFIED_TIME_DESC = '-last_modified_time',
2828
START_TIME = 'start_time',
2929
START_TIME_DESC = '-start_time',
30+
/**
31+
* NOTE: Rank is effective only when using `x_full_text` -parameter.
32+
*
33+
* NOTE: Rank should not be explicitly set, but left empty instead, when wanted.
34+
* The rank sorting needs a mandatory secondary order field and scoring annotation to queryset,
35+
* which are only activated when `x_full_text` -parameter is used and sort-parameter is left empty.
36+
*
37+
* However, in our own apps' URL we want sort-param to be set and visible, so it needs to be converted on search.
38+
*
39+
* Ref. [LINK-2422](https://helsinkisolutionoffice.atlassian.net/browse/LINK-2422)
40+
* */
41+
RANK_DESC = '-rank',
3042
}
3143

3244
export const isEventSortOption = (

0 commit comments

Comments
 (0)