我正在使用Angular和Firestore。
我想在两个字段上对Firestore数据库执行多次查询。现在,可以结合使用WHERE
语句了。
我的想法是合并值,然后将请求发送到数据库。例如,我想找回所有城市为洛杉矶,旧金山,纽约且“星级评分”为5、4的邮局。
所以我必须查询6种可能的组合:
Where city = Los Angeles
Where Stars = 5
...然后进行下一个查询
Where city = Los Angeles
Where stars = 4
...然后进行下一个查询
Where city = San Francisco
Where Stars = 5
...然后进行下一个查询
Where city = San Francisco
Where Stars = 4
等等。
我知道如何使用For
语句来处理一个字段和一个值,如下面的代码所示,但是我不知道如何组合它们(将组合组合成多个查询) ,然后等待所有对象(带有可观察对象或主题)执行以将它们组合在结果数组中。我在Stack上找到了两个答案,但没人能真正帮助我做出一个好的决定。
这一个,但仅在一个字段上,不可观察 Multiple Firestore queries, single promise / callback
另外一个 Firestore multiple range query 谁想到了“对查询中的一个字段执行过滤,而对客户端代码中的另一个字段执行过滤”。 如果您的结果很少,那么此解决方案是很好的选择,但是如果结果很多,则可以减慢该过程,并取回我们不需要的数据。
export class AnnoncesListComponent implements OnInit {
queryParams: { departement:string, secteurAct:string };
subscriptionChange:Subscription;
annoncesSubscription:Subscription;
departementGet: any;
secteurActGet: any;
annonceQuery: Annonce[];
isFetchingData:boolean = false;
constructor(
private activeRoute : ActivatedRoute,
private annnonceService: AnnoncesService
) { }
ngOnInit() {
//Get QUERYPARAMS FROM THE URL
this.departementGet = decodeURIComponent(this.activeRoute.snapshot.queryParams['departement']);
this.secteurActGet = decodeURIComponent(this.activeRoute.snapshot.queryParams['secteurActivite']);
this.departementGet = this.departementGet.split('_B2-');
this.secteurActGet = this.secteurActGet.split('_B2-');
//FOR - TO QUERIES ALL THE DATA NEEDED - FIRST QUERY
for (var i = 0; i < this.secteurActGet.length; i++) {
this.annoncesSubscription = this.annnonceService.getAnnonces('secteurActivite', this.secteurActGet[i])
.subscribe( responseData => {
this.isFetchingData = false
this.annonceQuery = responseData.map(item => {
return {
id : item.payload.doc.id,
secteurAct : item.payload.doc.get('secteurActivite'),
departement : item.payload.doc.get('departement'),
region : item.payload.doc.get('region'),
description : item.payload.doc.get('description'),
infosClefs : item.payload.doc.get('name'),
} as Annonce;
})
console.log(this.annonceQuery);
});
//FOR - TO QUERIES ALL THE DATA NEEDED - SECOND QUERY
for (var i = 0; i < this.departementGet.length; i++) {
this.annoncesSubscription = this.annnonceService.getAnnonces('secteurActivite', this.departementGet[i])
.subscribe( responseData => {
this.isFetchingData = false
this.annonceQuery = responseData.map(item => {
return {
id : item.payload.doc.id,
secteurAct : item.payload.doc.get('secteurActivite'),
departement : item.payload.doc.get('departement'),
region : item.payload.doc.get('region'),
description : item.payload.doc.get('description'),
infosClefs : item.payload.doc.get('name'),
} as Annonce;
})
console.log(this.annonceQuery);
});
};
我的结果是两个没有组合的分离数据,并且每次迭代都创建一个可观察的数据。
答案 0 :(得分:0)
我相信使用rxjs / forkJoin处理多个并行请求是一种好方法。
ForkJoin接受可观察变量数组作为其第一个参数,并返回一个可观察变量,一旦其所有传递的可观察变量都完成,该观察变量就会发出。
我已经将您的代码重构为易于阅读的代码,并且利用forkJoin并行处理部门和部门,然后输出每个结果数据的数组。
如果您正在处理的数据量很大,我什至建议您看一下WebWorkers,以便将cpu密集型操作拆分为多个线程并避免阻塞主线程。
// map array of departments into an array of Observables
const departmentsRequests = this.departementGet.map((departement) => {
return this.annnonceService.getAnnonces('departement', departement);
});
const secteurActiviteRequests = this.secteurActGet.map((secteur) => {
return this.annnonceService.getAnnonces('secteurActivite', secteur);
});
// forkJoin takes all Observables and emits once to its subscription
this.annoncesSubscription = forkJoin([
forkJoin(departmentsRequests),
forkJoin(secteurActiviteRequests),
]).subscribe(([departaments, secteurs]) => {
this.isFetchingData = false;
// all data has been loaded in parallel from firestore, handle it here
});
答案 1 :(得分:0)
服务中获取数据的功能就是这个:
getAnnonces(champ, valeur){
return this.firestore.collection('annonce', ref => ref.where(champ, '==', valeur)).snapshotChanges();
}
我让你编码,但是当我尝试输出结果时:
// forkJoin takes all Observables and emits once to its subscription
this.annoncesSubscription = forkJoin([
forkJoin(departmentsRequests),
forkJoin(secteurActiviteRequests),
]).subscribe(([departements, secteurs]) => {
this.isFetchingData = false;
// all data has been loaded in parallel from firestore, handle it here
console.log(departements);
});
没有结果。我尝试使用.get()而不是.snapshotChanges(),但他给了我[QuerySnapshot]