skip to Main Content

I have a question about Firestore search, collectiongroups, and something similar like that.

I have 2 main-collections: /users and /hobbies

Every user-doc in users has a subcollection "/hobbies", where I store the hobby-id from "hobbies", the user has chosen.
Now I want to search for users with a specific hobby and some more filters like age, hometown, online-status.

I can use collectionGroups, first search for the hobby and then use the loaded user-ids to get their data and filter it afterward, but then I will load hundreds of user-docs with the specific hobby but only get a few users with, for example, age = 30.

Isn’t there any better way to get these data?

I tried collectionGroups, but this results in a huge amount of users with a specific hobby, but only a few users have the age I am searching for. This is an inefficient solution.

2

Answers


  1. Isn’t there any better way to get these data?

    Certainly is. If you want to get all users who share a specific hobby and are, for example, 30 years old, then I recommend the following structure, where there is no need for any hobbies sub-collection:

    db
    |
    --- users (collection)
         |
         --- $uid (document)
              |
              --- age: 30
              |
              --- hometown: "New York"
              |
              --- onlineStatus: "offline"
              |
              --- hobbies: ["fishing", "dancing", "hiking"]
    

    The following query:

    db.collection("users")
      .whereArrayContains("hobbies", "fishing")
      .whereEqualTo("age", 30);
    

    Will only return the users who share the "fishing" hobby and are 30 years old. If you need other filters, you can chain as many whereEqualTo you want:

    db.collection("users")
      .whereArrayContains("hobbies", "fishing")
      .whereEqualTo("age", 30)
      .whereEqualTo("hometown", "New York")
      .whereEqualTo("onlineStatus", "offline");
    
    Login or Signup to reply.
  2. Firestore queries can only filter on data that is present in the documents that it returns.

    Alex’s solution ensures this is the case by moving (or copying) the hobbies into each user document. This is one excellent solution to the problem

    As an alternative, you can also keep your current data structure but include the user’s age in each hobby document. With that you’d keep the collection group query, but can now filter for the age on the hobby documents too.

    All of these approaches have their advantages and disadvantages, so you’ll have to consider what works best for each use-case

    This type of adapting the data model for your application’s use-cases is incredibly common when dealing with NoSQL databases. If you’re new to this domain, I recommend reading NoSQL data modeling and watching Get to know Cloud Firestore.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search