2

my database on firestore looks like this:

Candidates
    |
    |______ID_1
    |        |_______likeDislikeSuper
    |        |              |___________ID_1
    |     ( data )                        |_______value: n
    |
    |______ID_2
    |        |_______likeDislikeSuper
    |        |              |___________ID_2
    |     ( data )                        |_______value: n

i want retrieve (data) from candidates where value == n

firestore()
  .collection('candidates')
  .where('candidates/ID_1/likeDislikeSuper/ID_1', '==', 'n')
  .get();

**Candidates is a Collection, ID's are doc's, likeDislikeSuper is a subcollection of Candidates.

so... first params of where is a camp value, not support a path

does anyone know any way around this problem?

how could I return candidate documents using that value as a filter?

enter image description here

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
Remato
  • 93
  • 9
  • Your query is definitely not right. "/" is not a field separator, and you don't repeat the name of the collection in the field path. But it's not clear to me what your structure is. Are you showing nested maps in a single document, or do you have subcollections nested under documents in Candidates? Please edit the question to be more clear abou the data you're working with. A screenshot could be helpful. – Doug Stevenson Apr 15 '20 at 21:46
  • hey Doug thanks, i edit with a screenshot and info about the struct. Yes the `where` it's incorrect, I did that to "symbolize" what I would like to return. Why don't I know how to do it correctly – Remato Apr 15 '20 at 21:57

2 Answers2

3

If I understand correctly, you need to use a Collection Group query, as follows:

var likeDislikeSuperQuery = db.collectionGroup('likeDislikeSuper').where('value', '==', 'n');
likeDislikeSuperQuery.get().then(function (querySnapshot) {
    querySnapshot.forEach(function (doc) {
        console.log(doc.id, ' => ', doc.data());
    });
});

The query will return all the documents under the likeDislikeSuper subcollections (of all candidates) with a value field equal to 'n'.


Update following your comment:

If you want to get all the candidates document that are parent of the likeDislikeSuper documents returned by this query you could do as follows:

var likeDislikeSuperQuery = db.collectionGroup('likeDislikeSuper').where('value', '==', 'n');
likeDislikeSuperQuery.get().then(function (querySnapshot) {
    querySnapshot.forEach(function (doc) {
        const parentCandidateRef = doc.ref.parent.parent;
        console.log('parentCandidate path: ', doc.ref.parent.parent.path);
    });
});

However, this is not the most efficient approach, because several likeDislikeSuper documents may have the same parent candidates document.

You could duplicate your data and, for example, have a main collection of likeDislike documents for each liker/disliker ID which contain an array of candidateIds (or a sub collection of candidates document if you think the array could be so large that the document would reach the 1 MiB size limit).

Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
  • would that return the "candidates" data collection? or would it return data from the "likeDislikeSuper" collection? I was a little confused by the documentation – Remato Apr 15 '20 at 21:51
  • ok i try, but return the likeDislikeSuper documents, i want retrieve candidates documents :/ – Remato Apr 15 '20 at 22:04
  • What do you mean by `camp` value in your question?? – Renaud Tarnec Apr 15 '20 at 22:09
  • the first param of `where`, where(fieldPath, operation, value) – Remato Apr 15 '20 at 22:15
  • by the code I think that's right! but I now have an error that I had before, and I don't know how to solve it ` Error: [firestore/failed-precondition] operation was reject because the system is not a state required for the operation's execution. Ensure your query has been indexed via the firebase console. ` thanks for your patience, i'm working with firebase for a little while – Remato Apr 15 '20 at 23:22
  • Yes, as explained in the reffered to in my answer [documentation](https://firebase.google.com/docs/firestore/query-data/queries#collection-group-query): "Before using a collection group query, you must create an index that supports your collection group query. You can create an index through an error message, the console, or the Firebase CLI... For the web and mobile SDKs, you must also create rules that allow your collection group queries". – Renaud Tarnec Apr 16 '20 at 07:44
0

If you want to query a user's likeDislikeSuper subcollection, you will have to build a CollectionReference to it:

firestore()
  .collection('candidates')
  .doc('ID_1')
  .collection('likeDislikeSuper')
  .where('ID_1', '==', 'n')
  .get();
Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • I want to use a sub-collection value of "likeDislikeSuper" in where (), to retrieve candidate documents – Remato Apr 15 '20 at 22:20
  • Sorry, I don't really know what you're saying. In your screenshot, likeDislikeSuper is a subcolleciton. We can't see its document fields or values. Please edit the question to show an example of the documents you want your query to find. – Doug Stevenson Apr 15 '20 at 22:22