简体   繁体   中英

How to search in Firestore using multiple fields of documents for android?

I'm using a Firebase Firestore for android to store data. I tried to search data from documents.

My Firestore structure is:

Collection (Products) - Document (Auto Generated ID) - Field (NumberOfPeople,OfferStartDate,OfferEndDate,OfferPrice,Location)

I wrote query for search data on those fields.

CollectionReference collectionOfProducts = db.collection("Products");

collectionOfProducts
                    .whereEqualTo("Location", location)
                    .whereGreaterThanOrEqualTo("OfferPrice", offerPrice)
                    .whereLessThanOrEqualTo("OfferPrice", offerPrice)
                    .whereGreaterThanOrEqualTo("OfferStartDate", date)
                    .whereLessThanOrEqualTo("OfferEndDate", date)
                    .get()

I want search result like this: An offer which is between start date and end date, where offer price is greater than equal or less than equal on give price range. This query is not working in android studio.

How to do this in firestore firebase?

To the best of my knowledge, Firestore only lets you use where<Greater/Less>ThanOrEqualTo() and where<Greater/Less>Than() a single field and all other filter operations on other fields can only be whereEqualTo().

Some workarounds for your specific case include -

1) Modifying your query to

collectionOfProducts
                    .whereGreaterThanOrEqualTo("OfferStartDate", date)
                    .whereEqualTo("Location", location)
                    .get() 

And then performing the subsequent filtering on the result in your app code.

Alternately, you can perform your filter on "OfferPrice" and "Location" in your query and the remaining filters can be applied to the query result.

2) You can use firebase functions or other server code to write logic that performs customized filtering and fetch the result that way.

i was having same issue with this, but i found a work around that takes sometime to write.

lets say you want to search for a particular keyword(in this case the value of a field inside a document), and you want firebase to search multiple field instead of just looking for 1 particular field.

this is what you want to do.

const searchTerm = document.createElement('input')

db.collection('collection').where('field1', '==', `${searchTerm.value}`)
.get()
.then((snapshot) => {
     if(snapshot.size === '0'){
       db.collection('collection').where('field2', '==', `${searchTerm.value}`)
       .get()
       .then((snapshot) => {
         if(snapshot.size === 0) {
         db.collection......and repeat
         }
        })
     }
})

in summary, the above code is basically telling js to search for the term again with a different field if the result of the previous query is 0. I know this solution might not be able to work if we have a large quantity of fields. But for folks out there that are working with small number fields, this solution might be able to help.

I really do hope firestore one day would allow such feature, but here is the code it worked fine for me.

the problem I have now is to allow search input to be able to search without have me to complete the word. I do currently have an idea how this would be, but just need some time to put together.

According to the official documentation regarding Cloud Firestore queries, please note that there some query limitations :

In a compound query, range (<, <=, >, >=) and not equals (!=, not-in) comparisons must all filter on the same field .

So a Query object that contains a call to both methods:

.whereGreaterThanOrEqualTo("OfferStartDate", date)
.whereLessThanOrEqualTo("OfferEndDate", date)

Is actually not possible, as "OfferStartDate" and "OfferEndDate" are different properties.

The best solution I can think of is to use only one of these method calls and do the other filtering on the client.

Another possible solution might be to use denormalization and duplicate the data in certain intervals. In this way, you'll always know the time periods and you'll be able to create the corresponding queries.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM