I am trying to optimize the performances of my keyword search engine by sending aggregations/facet query and the actual search query in parallel.
I have tried many solutions, and in particular that one:
Angular2: which is the best way to make multiple sync calls with Observables?
The problem is that this solutions uses forkJoin that sends the call in parallel but wait for all http get to return. This defeat the point of my parallel calls. My understanding is that the solution is to use the same type of code but using mergeMap instead.
My existing code is the following:
ngOnInit(): void {
this.route.queryParamMap
.pipe(
// extract parameters
switchMap(params => {
const requestedQuery = params.get('query');
if (this.query !== requestedQuery) {
// we reset the results and criteria
this.results = undefined;
this.aggregationCriteria = [];
}
this.query = requestedQuery;
// set the search field
this.searchForm.get('search').setValue(this.query);
// extract the page if present
const page = this.extractPageFromParameters(params);
// extract the aggregations if there are some
// we consider all parameters as potential aggregations, except `query` and `page`
this.aggregationCriteria = this.extractCriteriaFromParameters(params);
// launch the search
return this.searchService.search(this.query, true, this.aggregationCriteria, page)
// handle a potential error, by returning no result
// but allow to trigger a new search
.pipe(
catchError(() => EMPTY)
);
})
)
.subscribe(results => {
this.loading = false;
// sets the results and the aggregations if there are some
this.results = results;
if (results.aggregations.length) {
this.aggregations = results.aggregations;
}
});
this.suggesterTypeahead = this.searchService.getSuggesterTypeahead();
}
I have tried the following, among many things, but this last version doesn't compile and I am getting stuck. Any suggestions or hint would be much welcomed.
ngOnInit(): void {
this.route.queryParamMap
.pipe(
// extract parameters
switchMap(params => {
const requestedQuery = params.get('query');
if (this.query !== requestedQuery) {
// we reset the results and criteria
this.results = undefined;
this.aggregationCriteria = [];
}
this.query = requestedQuery;
// set the search field
this.searchForm.get('search').setValue(this.query);
// extract the page if present
const page = this.extractPageFromParameters(params);
// extract the aggregations if there are some
// we consider all parameters as potential aggregations, except `query` and `page`
this.aggregationCriteria = this.extractCriteriaFromParameters(params);
// launch the search and handle a potential error, by returning no result
// but allow to trigger a new search
// return this.searchService.search(this.query, this.aggregationCriteria, page)
// .pipe(
// catchError(() => EMPTY),
// );
return map(
searchQuery => {
return this.searchService.search(this.query, this.aggregationCriteria, page)
.pipe(
catchError(() => EMPTY),
);
},
aggQuery => {return this.searchService.aggregate(this.query, this.aggregationCriteria) // ERROR: "TS7006: Parameter 'aggQuery' implicitely has 'any' type "
.pipe(
catchError(() => EMPTY)
);
}
);
}))
.subscribe(results => {
this.loading = false;
if (results.aggregations.length) {//ERROR: "TS2339: Property aggregation does not exist on type '{}'"
// sets the aggregations if there are some
this.aggregations = results.aggregations;
} else {
this.results = results;
}
});
this.suggesterTypeahead = this.searchService.getSuggesterTypeahead();
}