Home > OS >  What's the ideal data modeling for app with multi-filters?
What's the ideal data modeling for app with multi-filters?

Time:05-24

Viewed the Firestore docs Google's I/O 2019 webinar, but I'm still not clear about the right data modeling for my particular use case.

  1. App lets pro service providers register and publish one or more of their services in pre-defined categories (Stay, Sports, Wellness...) and at pre-defined price points (50$, 75$, 100$...).
  2. Users on the homepage are to filter down first with a price point slider - see wireframe), e.g: 199€, then and optionally by selecting the category, eg: all 'Sports' (at 199€) and the location (e.g: all sports at 199€ in the UK). Optionally because users can also build their list with a button as soon as the price is selected. The same 'build list' button is after the category selection and after the location selection. So 3 depths of filtering are possible.

What would be the ideal data structure, given that I want to avoid thousands of reads each time there's filtering. Three root-level collections (service providers, price points, service categories?) with their relevant documents? I understand and accept denormalization for the purpose of my filtering.

Here's the wireframe for a better understanding of the filtering:

homepage

search result after first 199EUR price selection

further filtering after 'Sports' category selection

Location filtering

proposed data modeling

CodePudding user response:

App lets pro service providers register and publish one or more of their services in pre-defined categories (Stay, Sports, Wellness...) and at pre-defined price points (50$, 75$, 100$...).

Since you're having pre-defined categories, prices, and locations, then the simplest solution for modeling such a database would be to have a single collection of products:

Firestore-root
  |
  --- products (collection)
        |
        --- $productId (document)
               |
               --- name: "Running Shoe"
               |
               --- category: "Sport"
               |
               --- price: 199
               |
               --- location: "Europe"
               |
               --- country: "France"

In this way, you can simply perform all queries that you need. Since you didn't specify a programming language, I'll write the queries in Java, but you can simply convert them into any other programming language. So for example, you can query all products with a particular price:

FirebaseFirestore db = FirebaseFirestore.getInstance();
Query queryByPrice = db.collection("products").whereEqualTo("price", 199);

If you need to query by price, category and location, then you have to chain multiple whereEqualTo() methods:

Query queryByPrice = db.collection("products")
                       .whereEqualTo("price", 199)
                       .whereEqualTo("category", "Sport")
                       .whereEqualTo("location", "Europe");

If you, however, need to order the results, ascending or descending, don't also forget to create an index.

What would be the ideal data structure, given that I want to avoid thousands of reads each time there's filtering.

If you don't need to have all the results at once, then you have to implement pagination. If you need to know the number of products that exist in the sports category ahead of time, that is not possible without performing a query and counting the available products. I have written an article regarding this topic called:

Another feasible possible solution would be to create a single document that contains all those numbers. In other words, exactly what you're displaying to the users, everything that exists in those screenshots. In this way, you'll only have to pay a single read operation. When the users click on a particular category, only then you should perform the actual search.

I understand and accept denormalization for the purpose of my filtering.

In this case, there is no need to denormalize the data. For more info regarding this kind of operation, please check my answer below:

  • Related