Google cloud firestore Firestore db:查询数组以查找具有特定值的文档

Google cloud firestore Firestore db:查询数组以查找具有特定值的文档,google-cloud-firestore,react-native-firebase,Google Cloud Firestore,React Native Firebase,如果我像下面这样查询,它将按预期返回文档。 我还知道firestore查询仅在完全对象匹配时返回结果 return firestore() .collection(`stores`) .where('servicesList', 'array-contains-any', [ { price: 24, serviceName: 'service1', },

如果我像下面这样查询,它将按预期返回文档。 我还知道firestore查询仅在完全对象匹配时返回结果

  return firestore()
        .collection(`stores`)
        .where('servicesList', 'array-contains-any', [
          {
            price: 24,
            serviceName: 'service1',
          },
        ])
        .onSnapshot((querySnapshot) => {
        ...
          });
        });
我有一个带有这些数组的存储集合,在这里我需要对过滤器进行不同的查询

e.g. return all stores where Service Name = "Service1" and Price < 20 
or return all stores where price > 20 etc.. 
例如,退回Service Name=“Service1”和价格<20的所有门店
或者退回价格>20等的所有门店。。
我的文档结构如下所示:

实现这一目标的有效方法应该是什么

一种解决方案是在第一次加载时获取所有存储,并在客户端进行筛选。 我想知道是否可以使用查询来实现这一点


感谢

这在Firestore查询中是不可能完成的,正如您在本文中看到的,您只能查询整个对象,而不能查询其中的单个字段

对于您建议的那些更复杂的查询,您有两种选择,或者按照您提到的那样在客户端完成所有操作,或者更改Firestore结构。既然你已经提到你对如何做第一个选项有想法,我将解释我将如何使用后者,你可以尝试这样的结构:

Store Collection
field1
...
fieldN
serviceIds:[]
    ServicesOffered SubCollection
        serviceId
        price

Service Collection
    serviceName   
        
firestore()
    .collection(`services`)
    .where('serviceName', '==', "service1")
    .get()
    .then(function(documentSnapshot) => {
        //This is the Id of the service to be searched
        var id = documentSnapshot.id;
        firestore().collection(`stores`)
                   .where('servicesList', 'array-contains', id)
                   .get()
                   .then(function(querySnapshot) => {
                        //query with the results of every store that contains the service
                        querySnapshot.forEach(function(doc) {
                           firestore().collection(`stores`)
                                      .doc(doc.id)
                                      .collection(`servicesOffered`)
                                      .where('serviceId', '==', id)
                                      .where('price', '>', 20)
                                      .get()
                                      .then(function(documentFinalSnapshot) => {
                                          // This is the price filter result
                                          if (documentFinalSnapshot.exists) {
                                              //add it to your return
                                          }
                                      })

                        });
                   });
    });
因此,只有serviceName的单独服务集合,一个包含引用服务集合文档的ServiceUID数组的存储集合,以及一个ServicesForfered子集合,该子集合给出该存储中所述服务的具体价格。使用此结构,您可以按如下方式查询建议的查询:

Store Collection
field1
...
fieldN
serviceIds:[]
    ServicesOffered SubCollection
        serviceId
        price

Service Collection
    serviceName   
        
firestore()
    .collection(`services`)
    .where('serviceName', '==', "service1")
    .get()
    .then(function(documentSnapshot) => {
        //This is the Id of the service to be searched
        var id = documentSnapshot.id;
        firestore().collection(`stores`)
                   .where('servicesList', 'array-contains', id)
                   .get()
                   .then(function(querySnapshot) => {
                        //query with the results of every store that contains the service
                        querySnapshot.forEach(function(doc) {
                           firestore().collection(`stores`)
                                      .doc(doc.id)
                                      .collection(`servicesOffered`)
                                      .where('serviceId', '==', id)
                                      .where('price', '>', 20)
                                      .get()
                                      .then(function(documentFinalSnapshot) => {
                                          // This is the price filter result
                                          if (documentFinalSnapshot.exists) {
                                              //add it to your return
                                          }
                                      })

                        });
                   });
    });
@新手会这么做吗?