From 6b3dbb59a5d32ff5264f28e1c82195007c5f52c6 Mon Sep 17 00:00:00 2001 From: Jay Quan Date: Tue, 5 Dec 2023 14:04:24 +0100 Subject: [PATCH 1/3] added mongo query .sort() to sort ES query result --- src/datasets/datasets.service.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/datasets/datasets.service.ts b/src/datasets/datasets.service.ts index 08ff92f73..ade96cf8a 100644 --- a/src/datasets/datasets.service.ts +++ b/src/datasets/datasets.service.ts @@ -122,9 +122,12 @@ export class DatasetsService { filter.fields as IDatasetFields, modifiers.limit, modifiers.skip, + modifiers.sort, ); + datasets = await this.datasetModel .find({ _id: { $in: esResult.data } }) + .sort(modifiers.sort) .exec(); } From 8815cbc53921d4adafeee91b04ec10daf29e491a Mon Sep 17 00:00:00 2001 From: Jay Quan Date: Tue, 5 Dec 2023 14:06:58 +0100 Subject: [PATCH 2/3] explicitly added scientificMetadata.runNumber.value to the field mapping for sorting purpose --- src/elastic-search/configuration/datasetFieldMapping.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/elastic-search/configuration/datasetFieldMapping.ts b/src/elastic-search/configuration/datasetFieldMapping.ts index 20c849e67..24c78ec15 100644 --- a/src/elastic-search/configuration/datasetFieldMapping.ts +++ b/src/elastic-search/configuration/datasetFieldMapping.ts @@ -32,6 +32,15 @@ export const datasetMappings: MappingObject = { scientificMetadata: { type: "nested", dynamic: true, + properties: { + runNumber: { + properties: { + value: { + type: "long", + }, + }, + }, + }, }, history: { type: "nested", From f41c963d5794507324f42cb7d929e2cbb719a1b1 Mon Sep 17 00:00:00 2001 From: Jay Quan Date: Tue, 5 Dec 2023 14:09:35 +0100 Subject: [PATCH 3/3] added sort query to the elasticsearch --- src/elastic-search/elastic-search.service.ts | 41 +++++++++++++++++++- src/elastic-search/providers/fields.enum.ts | 7 ++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/elastic-search/elastic-search.service.ts b/src/elastic-search/elastic-search.service.ts index dd6a3b5c1..ca2e7be42 100644 --- a/src/elastic-search/elastic-search.service.ts +++ b/src/elastic-search/elastic-search.service.ts @@ -12,6 +12,7 @@ import { SearchTotalHits, SearchRequest, AggregationsAggregate, + SortOrder, } from "@elastic/elasticsearch/lib/api/types"; import { IDatasetFields } from "src/datasets/interfaces/dataset-filters.interface"; import { @@ -31,6 +32,8 @@ import { transformFacets, } from "./helpers/utils"; +import { SortFields } from "./providers/fields.enum"; + @Injectable() export class ElasticSearchService implements OnModuleInit { private esService: Client; @@ -255,6 +258,7 @@ export class ElasticSearchService implements OnModuleInit { searchParam: IDatasetFields, limit = 20, skip = 0, + sort?: Record, ): Promise<{ totalCount: number; data: string[] }> { const defaultMinScore = searchParam.text ? 1 : 0; @@ -263,15 +267,48 @@ export class ElasticSearchService implements OnModuleInit { const searchOptions = { track_scores: true, - body: searchQuery, + sort: [{ _score: { order: "desc" } }], + query: searchQuery.query, from: skip, size: limit, - sort: [{ _score: { order: "desc" } }], min_score: defaultMinScore, track_total_hits: true, _source: [""], } as SearchRequest; + if (sort) { + const sortField = Object.keys(sort)[0]; + const sortDirection = Object.values(sort)[0]; + + // NOTE: To sort datasetName field we need to use datasetName.keyword field, + // as elasticsearch does not have good support for text type field sorting + const isDatasetName = sortField === SortFields.DatasetName; + const fieldForSorting = isDatasetName + ? SortFields.DatasetNameKeyword + : sortField; + + const isNestedField = fieldForSorting.includes( + SortFields.ScientificMetadata, + ); + + if (isNestedField) { + searchOptions.sort = [ + { + [`${SortFields.ScientificMetadataRunNumberValue}`]: { + order: sortDirection, + nested: { + path: SortFields.ScientificMetadata, + }, + }, + }, + ]; + } else { + searchOptions.sort = [ + { [fieldForSorting]: { order: sortDirection } }, + ]; + } + } + const body = await this.esService.search(searchOptions); const totalCount = (body.hits.total as SearchTotalHits)?.value || 0; diff --git a/src/elastic-search/providers/fields.enum.ts b/src/elastic-search/providers/fields.enum.ts index f5b691e5d..7cf919dc0 100644 --- a/src/elastic-search/providers/fields.enum.ts +++ b/src/elastic-search/providers/fields.enum.ts @@ -22,3 +22,10 @@ export enum QueryFields { DatasetName = "datasetName", Description = "description", } + +export enum SortFields { + DatasetName = "datasetName", + DatasetNameKeyword = "datasetName.keyword", + ScientificMetadata = "scientificMetadata", + ScientificMetadataRunNumberValue = "scientificMetadata.runnumber.value", +}