2

If I query like below it returns the document as expected. I also know that firestore query return results only when full object matches.

  return firestore()
        .collection(`stores`)
        .where('servicesList', 'array-contains-any', [
          {
            price: 24,
            serviceName: 'service1',
          },
        ])
        .onSnapshot((querySnapshot) => {
        ...
          });
        });

I have stores collection with these arrays where I need to make different queries for filters.

e.g. return all stores where Service Name = "Service1" and Price < 20 
or return all stores where price > 20 etc.. 

my document structure is like this : document structure

What should be an efficient way to achieve this ?

One solution is to get all stores on first load and filter on client side. I wonder if this can be done using the query.

Thanks

rookie
  • 21
  • 1

1 Answers1

1

This is not possible to be done in a Firestore query, as you can see in this community answer, you can only query the entire object and not individual fields of it.

For those more complex queries you are proposing you have 2 options, either do it all on the client side as you mentioned, or change you Firestore structure. Since you already mentioned you have an idea of how to do the first option I will explain how I would go with the latter, you could try a structure like this:

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

Service Collection
    serviceName   
        

So, a separate Service collection with the serviceName only, a Store Collection with an array of serviceUids which refers to the Service collection's documents and with a ServicesOffered subcollection that gives the specific price in that store for said service. With this structure you could query the proposed queries like this:

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
                                          }
                                      })

                        });
                   });
    });
Ralemos
  • 5,571
  • 2
  • 9
  • 18