我正在尝试通过并行发送聚合/方面查询和实际搜索查询来优化关键字搜索引擎的性能。
我尝试了许多解决方案,尤其是其中一种:
Angular2: which is the best way to make multiple sync calls with Observables?
问题是此解决方案使用forkJoin并行发送呼叫,但等待所有http返回。这打败了我的并行通话点。我的理解是,解决方案是使用相同类型的代码,但改用mergeMap。
我现有的代码如下:
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();
}
在很多方面,我都尝试了以下方法,但是此最新版本无法编译,我陷入了困境。任何建议或提示都将受到欢迎。
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();
}
答案 0 :(得分:1)
如果您希望所有请求并行执行并使它们在完成时发出,那么您真正想要的是合并在这里:
return merge(
this.searchService.search(this.query, this.aggregationCriteria, page)
.pipe(
catchError(() => EMPTY),
);
},
this.searchService.aggregate(this.query, this.aggregationCriteria)
.pipe(
catchError(() => EMPTY)
);
);
缺点是在您的订阅处理程序中,除非您进行一些映射以帮助您弄清楚,否则您将真正不知道哪个是哪个。
地图不是可观察的,它是一个运算符,合并将获取两个可观察的对象并“合并”它们的结果。
顺便说一句,forkJoin并没有达到并行调用的目的,这只是一个不同的用例,在这种情况下,您想并行进行调用(即在开始另一个调用之前不要等待一个),但是要等到您可以采取所有行动结果,或者只是需要知道哪个结果属于哪个行动。