2

I have an app that returns a list of health foods. There will be approximately 10000-20000 foods (documents) in the product collection.

These foods are queried by multiple fields using arrayContains. This may be categories, subcategories and when the user searches in the search bar it is an arrayContains on the keywords array.

With so many products I plan to paginate the results of query as I get the documents. The issue is that I need to know the amount of results to display the total of results to the user.

I have read that for a query you are charged one read and then if you get the documents then they are further charged per document. Is there a way of getting the number of results for a query without getting all the documents.

I have seen this answer here:

Get size of the query in Firestore

But in this example they say to use a counter which doesn't seem practical as I am using a query on keyword when the user searches and I am using a mixture of categories, subcategories when the user filters.

Thanks

Nicholas Muir
  • 2,897
  • 8
  • 39
  • 89

2 Answers2

1

With so many products I plan to paginate the results of query as I get the documents.

That's a very good decision since getting 10000-20000 foods (documents) at once is not an option. Reason one is the cost, it will be quite expensive and second is that you'll get an OutOfMemoryError when trying to load such enormous amount of data.

The issue is that I need to know the amount of results to display the total of results to the user.

There is no way in Firestore so you can know in advance the size of the result set.

Is there a way of getting the number of results for a query without getting all the documents.

No, you have to page through all the results that are returned by your query to get the total size.

But in this example they say to use a counter which doesn't seem practical as I am using a query on keyword when the user searches

That's correct, that solution doesn't fit your needs since it solves the problem of storing the number of all documents in a collection and not the number of documents that are returned by a query. As far as I know, it's just not scalable to provide that information, in the way this cloud hosted, NoSQL, realtime database needs to "massively scale".

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • This doesn't seem to answer the question. Just reaffirms what OP stated in their question. I take it there's no good way of doing this with firestore/base alone? One can create indices in Algolia or another search engine and query on that. – Logan Apr 10 '21 at 17:35
0

For any future lurker, a "solution" to this problem is to paginate results with a cursor until the query doesn't return any more documents. When the query snapshot is empty, return undefined for your cursor and handle from there:

const LIMIT = 100
const offset = req.query.offset

const results = db.collection(COLLECTION)
   .offset(offset)
   .limit(LIMIT)
   .get()

const docs = results.docs.map(doc => doc.data())

res.status(200).send({
    data: docs,
    // Return the next offset or undefined if no docs are returned anymore.
    offset: docs.length > 0 ? offset + LIMIT : undefined
})
P Fuster
  • 2,224
  • 1
  • 20
  • 30
  • How does this give you the total number of documents in Firestore database or in a queried documents with array contains? I already said I was paginating. Thanks for your answer but you are answering a totally different question, what you have written above is not applicable. – Nicholas Muir Jul 17 '21 at 11:51