Firestore - 一个循环中的深度集合查询

Firestore - deep collection query in one loop

我有一个这样的 firestore 对象:

{
  countries:[
    country1: {
      cities: [
        city1: {date_added: timestamp},
        ...
      ]
    }
    ...
  ]
}

所以我想在一次查询中获得一个城市列表。我知道我可以去(我在 firestore 函数中)

const cities = [];

admin.firestore().collection('countries/')
    .get()
    .then(countriesSnapshot => {
      countriesSnapshot .forEach( countryDoc => {
        admin.firestore().collection('countries/' + countryDoc.id + '/cities/')
          .get()
          .then(citySnapshot => {
            citySnapshot.forEach( cityDoc => {
              cities.push(cityDoc.id);
            });
          }).catch();
      });
    }).catch();

但这会执行双重 foreach,我只想在所有问题都解决后才进行处理。我可以使用 promise.all 但我想知道是否有更简单的方法 - 比如

admin.firestore().collection('countries/{countryId}/cities').get().then(citySnapshot ...

如果要查询所有 cities 个集合,可以使用 collection group query:

let cities = db.collectionGroup('cities');
cities.get().then(function(querySnapshot) {
  querySnapshot.forEach(function(doc) {
    console.log(doc.id, ' => ', doc.data());
  });
});

这将 return 所有国家/地区的所有城市。

因此,看起来不可能在特定的子集合中实现这种情况 = Frank 的回答提供了一个在某些情况下可行但在我的情况下行不通的解决方案,因为我的名字在我的数据库中不是唯一的.

所以我的解决方案是让它在两个循环中发生,而不是在一个循环中发生在另一个循环中——使用 Promises。像这样:

admin.firestore().collection('countries/')
  .get()
  .then(countriesSnapshot => {
    const citiesPromises = [];
    countriesSnapshot.forEach( countryDoc => {
      citiesPromises.push(admin.firestore().collection('countries/' + countryDoc.id + '/cities/').get());
    });
    Promise.all(citiesPromises).then(resources => {
      for (const resource of resources) {
        resource.forEach( doc => {
          // do stuff with doc.id or doc.data()
        });
      }
    }).catch();
  }).catch();