diff --git a/apps/server-asset-sg/src/features/assets/search/asset-search.service.ts b/apps/server-asset-sg/src/features/assets/search/asset-search.service.ts index ed77f301..1075499e 100644 --- a/apps/server-asset-sg/src/features/assets/search/asset-search.service.ts +++ b/apps/server-asset-sg/src/features/assets/search/asset-search.service.ts @@ -197,21 +197,7 @@ export class AssetSearchService { * @param query The query to match with. */ async aggregate(query: AssetSearchQuery): Promise { - const [mapping, _total] = await this.searchAssetsByQuery(query); - const stats = await this.aggregateAssetIds([...mapping.keys()]); - if (stats !== null) { - return stats; - } - return { - total: 0, - assetKindItemCodes: [], - authorIds: [], - createDate: null, - languageItemCodes: [], - geometryCodes: [], - manCatLabelItemCodes: [], - usageCodes: [], - }; + return await this.aggregateAssetIds(query); } /** @@ -320,64 +306,104 @@ export class AssetSearchService { } } - private async aggregateAssetIds(assetIds: AssetId[]): Promise { - if (assetIds.length === 0) { - return null; - } - + private async aggregateAssetIds(query: AssetSearchQuery): Promise { interface Result { - aggregations: { - minCreateDate: { value: DateId }; - maxCreateDate: { value: DateId }; - authorIds: { - buckets: AggregationBucket[]; - }; - assetKindItemCodes: { - buckets: AggregationBucket[]; - }; - languageItemCodes: { - buckets: AggregationBucket[]; - }; - geometryCodes: { - buckets: AggregationBucket[]; - }; - usageCodes: { - buckets: AggregationBucket[]; - }; - manCatLabelItemCodes: { - buckets: AggregationBucket[]; - }; + minCreateDate: { value: DateId }; + maxCreateDate: { value: DateId }; + authorIds: { + buckets: AggregationBucket[]; + }; + assetKindItemCodes: { + buckets: AggregationBucket[]; + }; + languageItemCodes: { + buckets: AggregationBucket[]; + }; + geometryCodes: { + buckets: AggregationBucket[]; + }; + usageCodes: { + buckets: AggregationBucket[]; + }; + manCatLabelItemCodes: { + buckets: AggregationBucket[]; }; } + const defaultResult = () => + ({ + total: 0, + assetKindItemCodes: [], + authorIds: [], + createDate: null, + languageItemCodes: [], + geometryCodes: [], + manCatLabelItemCodes: [], + usageCodes: [], + } as AssetSearchStats); + interface AggregationBucket { key: K; doc_count: number; } + const aggregateGroup = async (query: AssetSearchQuery, operator: string, groupName: string, fieldName?: string) => { + const elasticDslQuery = mapQueryToElasticDsl({ ...query, [groupName]: undefined }); + return ( + await this.elastic.search({ + index: INDEX, + size: 0, + query: elasticDslQuery, + track_total_hits: true, + aggs: { + agg: { [operator]: { field: fieldName ?? groupName } }, + }, + }) + ).aggregations?.agg; + }; + + const elasticQuery = mapQueryToElasticDsl(query); const response = await this.elastic.search({ index: INDEX, size: 0, - query: { - terms: { - assetId: assetIds, - }, - }, + query: elasticQuery, track_total_hits: true, - aggs: { - authorIds: { terms: { field: 'authorIds' } }, - minCreateDate: { min: { field: 'createDate' } }, - maxCreateDate: { max: { field: 'createDate' } }, - assetKindItemCodes: { terms: { field: 'assetKindItemCode' } }, - languageItemCodes: { terms: { field: 'languageItemCodes' } }, - geometryCodes: { terms: { field: 'geometryCodes' } }, - usageCodes: { terms: { field: 'usageCode' } }, - manCatLabelItemCodes: { terms: { field: 'manCatLabelItemCodes' } }, - }, }); - const total = (response.hits.total as SearchTotalHits).value; - const { aggregations: aggs } = response as unknown as Result; + if (total === 0) { + return defaultResult(); + } + + const [ + assetKindItemCodes, + authorIds, + languageItemCodes, + geometryCodes, + manCatLabelItemCodes, + usageCodes, + minCreateDate, + maxCreateDate, + ] = await Promise.all([ + aggregateGroup(query, 'terms', 'assetKindItemCodes', 'assetKindItemCode'), + aggregateGroup(query, 'terms', 'authorIds'), + aggregateGroup(query, 'terms', 'languageItemCodes'), + aggregateGroup(query, 'terms', 'geometryCodes'), + aggregateGroup(query, 'terms', 'manCatLabelItemCodes'), + aggregateGroup(query, 'terms', 'usageCodes', 'usageCode'), + aggregateGroup(query, 'min', 'minCreateDate', 'createDate'), + aggregateGroup(query, 'max', 'maxCreateDate', 'createDate'), + ]); + const aggs = { + assetKindItemCodes, + authorIds, + languageItemCodes, + geometryCodes, + manCatLabelItemCodes, + usageCodes, + minCreateDate, + maxCreateDate, + } as unknown as Result; + const mapBucket = (bucket: AggregationBucket): ValueCount => ({ value: bucket.key, count: bucket.doc_count, diff --git a/libs/asset-viewer/src/lib/components/asset-search-filter-list/asset-search-filter-list.component.html b/libs/asset-viewer/src/lib/components/asset-search-filter-list/asset-search-filter-list.component.html index 4f6ed70a..1a28c822 100644 --- a/libs/asset-viewer/src/lib/components/asset-search-filter-list/asset-search-filter-list.component.html +++ b/libs/asset-viewer/src/lib/components/asset-search-filter-list/asset-search-filter-list.component.html @@ -1,6 +1,10 @@
  • -
  • diff --git a/libs/asset-viewer/src/lib/state/asset-search/asset-search.effects.ts b/libs/asset-viewer/src/lib/state/asset-search/asset-search.effects.ts index 50c343aa..e195caab 100644 --- a/libs/asset-viewer/src/lib/state/asset-search/asset-search.effects.ts +++ b/libs/asset-viewer/src/lib/state/asset-search/asset-search.effects.ts @@ -188,14 +188,11 @@ export class AssetSearchEffects { public updateStats$ = createEffect(() => { return this.actions$.pipe( - ofType(actions.getStats), + ofType(actions.getStats, actions.search), withLatestFrom(this.searchStore.select(selectAssetSearchState)), switchMap(([_, state]) => { return this.assetSearchService - .updateSearchResultStats({ - text: state.query.text, - polygon: state.query.polygon, - }) + .updateSearchResultStats(state.query) .pipe(map((searchStats) => actions.updateStats({ searchStats }))); }) );