1

I have collections named quests and quizzes, which have sub-collections inside their documents named published which will contain different published versions of the corresponding document.

  • quests/
    • published/
  • quizzes/
    • published/

quests and quizzes are also tagged and these tags are copied to published document. So all published documents have a tags field(an Array of Strings).

I want to query all the published quests which are related to given tag. Something along this

db
  .collectionGroup('published')
  // This query is not correct, regex syntax doesn't work here for path.
  // I have added it to show that I want to query only the published 
  // documents inside quests.
  .where(
    firebase.firestore.FieldPath.documentId(),
    '==',
    '/quests/*/published/*'
  )
  .where(
    'tags',
    'array-contains',
    'kinematics'
  )

--- EDIT ---

this is structure of quests, and quizzes also has the same structure. and it also has tags field.

  • quest when version 1.0 was published db structure of quests: version 1

  • quest when version 2.0 was published enter image description here

I want to fetch all the published quests that are related some particular tag, so here quests//published/2.0 should be one of the resulting documents, if I query with 'physics' tag, as version 1.0 it is not related only to 'kinematics'. Screenshot of only one quest is added here. there are multiple quests with multiple published version inside them relating to tag I want to query. I want to fetch all of them, excluding documents from quizzes//published/ with a single query.

skam
  • 357
  • 5
  • 18
  • 1
    Instead of describing how your database looks like, please add a screenshot of it. Please also provide more details about the query that you want to perform. – Alex Mamo Feb 06 '20 at 12:41
  • It's not clear to me what you're trying to accomplish. What does it mean to "run some condition on sub-collection group child1"? – Doug Stevenson Feb 06 '20 at 15:56
  • @DougStevenson I have edited the description. I think it is better now. Let me know If have to add anything. – skam Feb 07 '20 at 05:51
  • I still don't understand, especially the first where clause. It might help if you show actual document data and what you want to see from that in a query. – Doug Stevenson Feb 07 '20 at 05:55
  • @DougStevenson Sorry for not being clear. now? – skam Feb 07 '20 at 07:02
  • I think you're asking how to query all of the documents inside the *published* collection for documents that have a field *tags* (an array) that contains a specific tag. Is that correct? – Jay Feb 07 '20 at 17:51
  • **Update**: it turns out that querying a specific path may be possible after all, thanks to how `FieldPath.documentId()` is indexed for collection group indexes. Check @samthecodingman's answer here: https://stackoverflow.com/a/68049847 – Frank van Puffelen Jun 21 '21 at 16:20

1 Answers1

1

This part of your query is not possible:

  .where(
    firebase.firestore.FieldPath.documentId(),
    '==',
    '/quests/*/published/*'
  )

FieldPath.documentId() just can't be used as a filter in collection group queries. It's a known limitation. There are also no wildcard matches in Firestore, at all.

There's another problem with your requirement to "exclude documents from quizzes//published/". Firestore queries also cannot also exclude specific items based on inequality. Please read this other issue for more details. What you can do is store the name of the top-level collection (e.g. "quests") in a field in the documents of a subcollection, then filter to match documents with that field. But you can't exclude documents this way. If you want exclusion, you will need a boolean field that expresses this exclusion, such as "is_not_quiz", and set it appropriately for each document that is not a quiz.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • We decided to name the internal collections `publishedQuests` and `publishedQuizzes`. Thank you! – skam Feb 21 '20 at 11:43