Google Firestore: Filter documents where sub-key is between given value

Viewed 887

I am working on a browser game and I have a collection in firestore that looks like this:

{
    title: "doc 1",
    requirements: {
        level: {
            min: 2,
            max: 3
        }
    }
},
{
    title: "doc 2",
    requirements: {
        level: {
            min: 6,
            max: 8
        }
    }
},
{
    title: "doc 3",
    requirements: {
        level: {
            min: 8,
            max: 9
        }
    }
}

Is there any way to query for all documents, that match a given level like when I have a level of 8 I only want to fetch the documents "doc 2" and "doc 3" because the level requirements match?

I tried with something like

ref.where("requirements.level.min", "<=", level);
ref.where("requirements.level.max", ">=", level);

I also tried to change the structure in my documents to this:

{
    title: "doc 1",
    requirements: {
        level: [2, 3]
    }
},
{
    title: "doc 2",
    requirements: {
        level: [6, 7, 8]
    }
}

and filter it like this

ref.where("requirements.level", "array-contains", level)

But firestore always returns me all documents.

1 Answers

Array contains seems to be correct choice here. I've checked your example - recreated quite similar structure in my firestore (other doc has same structure but levels from 5 to 7) and run these queries:

const docs = firebase.firestore().collection('docs');
docs.where('requirements.levels','array-contains',2).get().then((snap) => {
    console.log(snap.docs.length); //<- outputs 1, correct
  });
docs.where('requirements.levels','array-contains',4).get().then((snap) => {
    console.log(snap.docs.length); //<- outputs 0, correct
  });
docs.where('requirements.levels','array-contains',5).get().then((snap) => {
    console.log(snap.docs.length); //<- outputs 1, correct
  });
Related