0

I'm creating an Ionic application using Firestore with Angularfire2.

My database structure is as follows:

- creators
  - CREATOR_ID
    - name (string)
    - description (string)
    - posts (map)
      - category1 (array)
        - [POST1, POST2, POST3]
      - category2 (array)
        - [POST3, POST4, ...]

A creator is able to create posts/articles. And when a creator creates an article he's able to specify which categories that post belongs to!

The thing about the aplication though is, when a user wants to filter by category, it will bring all the CREATORS that contain at least one post in the category the user selected (instead of bringing all the articles in that category).

So, based on the structure above I tried the following:

this.afs.collection<Creator>('creators', ref => ref.where("posts.category1", '>', ""));

But it returns nothing!

Do you guys have any suggestions?

Thanks!

Matheus
  • 79
  • 8

1 Answers1

1

As I see in your database schema, your category1 and category2 are arrays. The following where() function call:

.where("posts.category1", '>', "POST1")

Would have been worked, if your categories (category1 and category2) would have been of type Map and not arrays and you would have been queried for a particular post. To solve this, there are two approaches:

The first one would be to change the type of your categories from array -> map and use the above line code and the second one would be to use:

.where("posts.category1", , "array-contains", "POST1")

But note, none of the above approaches will help you find if an array contains at least one element. For that, you should add a listener and check if that particular array/map exists.

See here more informations.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Hey Alex, thanks for the help! Unfortunately I'm not looking for a single post. I'm looking for all the creators that have a specific key inside the posts map. So if I'm looking for category1, I want all the creators that have the key 'category1' inside the posts map. You mentioned listeners.. you mean, like, get all the creators and then in my application check the creators one by one if they have that category inside 'posts'? – Matheus Nov 05 '18 at 13:51
  • "I'm looking for all the creators that have a specific key inside the posts map." In your case, you should consider augmenting your data structure to allow a reverse lookup by creating a `posts` collection in which you should add as documents, every post a creator has (`rootRef -> posts(collection)->creatorId(document)->creatorPosts(collection)->postId(document)`). You can also take a look at my answer from this, **[post](https://stackoverflow.com/questions/53099589/how-to-select-locations-in-firestore-and-android/53100252#53100252)** for a better understanding. – Alex Mamo Nov 05 '18 at 14:58
  • Thanks! I'll try changing my data structure then! One last question, if you don't mind: suppose I have an array of IDs, like [POST_ID1, POST_ID2, POST_ID3, ...]. If I iterate over each of these IDS (using a forEach loop, for example) and request the post data itself from another collection (like the 'posts' collection in the rootRef), will I be charged for each ID in the array(like, each ID is one single call to the database)? Or will it be considered one single call to the Firestore database for all the ids? – Matheus Nov 05 '18 at 16:06
  • If you have an array of ids, it doesn't matter how many ids are within it, as long as you respect the limitation of 1Mib per document. So if you read a document that has a property of type array with 100 ids, you are charged for a single read operation. If you are using those 100 ids to make 100 more database calls, you be charged with new 100 read operations. You can also take a look at my answer from this **[post](https://stackoverflow.com/questions/53053768/what-is-the-correct-way-to-structure-this-kind-of-data-in-firestore/53057707)**. – Alex Mamo Nov 05 '18 at 16:36
  • 1
    Got it! Thank you for your help, Alex! – Matheus Nov 05 '18 at 16:53