skip to Main Content

In my collection "users", each user is defined by their name, list of hobbies, and skills:

Structure of a document in "users":

name : "Name"
hobbies: ["hobby1","hobby2","hobby3"]
skills: ["skill1","skill2","skill3"]

What I want is: Get all documents in the collection where one of those fields contains a specific word. The problem is that currently I get all documents and then I do a loop to retain the matching documents. But I would prefer to do a query instead (reads are expensive). So I was thinking to reorganize the document like this:

New structure:

data: ["Name","hobby1","hobby2","hobby3",skill1","skill2","skill3"]

So I could do a query with "where" and "array-contains". What do you think? Isn’t it strange?

2

Answers


  1. If you want to have a OR statement between the hobbies and skills then you can’t use a query that uses array-contains. As stated on this documentation:

    You can use at most one array-contains clause per query. You can’t combine array-contains with array-contains-any.

    What I would suggest is to combine the skills and hobbies into one.:
    e.g.:

    name : "Name"
    skillsandhobbies : ["Hobby1", "Hobby2", "Hobby3", "Skill1", "Skill2", "Skill3"]
    

    Then you can use this sample query to get all the documents that have hobbies or skills that contain a specific word:

    const q = query(collection(db, "users"), where("skillsandhobbies", "array-contains", "specific-word"));
    
    Login or Signup to reply.
  2. As I understood from your comments, you basically need to perform a successive search. You need to search the hobbies array for a particular word, and if you don’t get any results, you need to perform another search, in the skills array, for the exact same word, and if again you don’t get any results, you need to search for the name.

    Since you didn’t specify a particular programming language, I assume you’re using Flutter, as in the other questions of yours. So I will try to explain real quickly how to do it.

    First, you need to create the following query:

    final queryHobbiesByWord = users.where("hobbies", arrayContains: "word");
    

    Then you have to call get(). As soon as you get a successful callback, you have to check if the number of documents that exist inside the QuerySnapshot is greater than zero. If it is, then perform the logic you want, otherwise, inside the callback create another query that looks like this:

    final querySkillsByWord = users.where("skills", arrayContains: "word");
    

    Do the exact same thing as about. If the number of documents that exist inside the QuerySnapshot is greater than zero, then perform the logic you want, otherwise, inside the callback create another query that looks like this:

    final queryNameByWord = users.where("name", isEqualTo: "word");
    

    Again, perform the same operation as above, and that’s pretty much it. Don’t forget to perform each operation inside the callback of the previous one.

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