0
votes

I am stucked with firebase limitations. What I want to achieve is two Where array-contains in a single query and firestore doesn't allow this it is limited to one per query.

I have an array of keywords in my products collection. eg. keywords:['men','men-clothing', 'men-clothing-denim']

I want to search the products based on the array of keywords like if user searches for men clothing and filters the product by selecting brand say denim. Than the keyword appends frequently and ends up making a string 'men-clothing-brands-denim'. Now i want to search in my products collection the same keyword i am using Where('keywords', 'array-contains', 'men-clothing-brand-denim').

What's the problem here is i also have sorting i my app so if users select 'low to high' i also want to sort the product at the same time while applying filter. I am sorting the products based on keyword only.

Firestore is not allowing the two Where array-contains in a single query. I also want to sort my products when user apply's for filter.

For sorting i am using where('keywords', 'array-contains', 'men-clothing');

So in the end if i want to achieve both i need to write query as:

db.collection('products').where('keywords', 'array-contains', 'men-clothing').where('price', 'desc').where('keywords','array-contains', 'men-clothing-brand-denim').get()

and firestore doesn't support two where array-contains in the same query what is the best way to achieve this using firestore. This whole scenario comes under my e-commerce app search component where user searches for products and a list of products appears there user can filter and sort the products.

1

1 Answers

1
votes

I want to achieve is two Where array-contains in a single query and Firestore doesn't allow

You're totally right. If you will use more than one array-contains because the following error will occur:

Caused by: java.lang.IllegalArgumentException: Invalid Query. Queries only support having a single array-contains filter.

However, if you need to filter on men-clothing and men-clothing-brand-denim keywords at the same time, there is a workaround that can help you solve this problem. As you already noticed, you cannot use array-contains but you can make a little change in the logic of your database schema. So you should consider creating a new property for each individual value from your keywords array and then chain multiple where() method calls. Calling this method multiple times, it's perfectly valid.

Your schema should like this:

keywords: { 
    "men": true,
    "men-clothing": true,
    "men-clothing-denim": true
}

As you can see now, the keywords is not an array anymore, it's a Map. So using such a schema, you'll be able to find all the documents that match men-clothing and men-clothing-denim at the same time. The query that is needed looks something like this:

db.collection('products')
    .where("men-clothing", "==", true)
    .where("men-clothing-denim", "==", true);

You can also add an order by the desired property call but don't forget to create an index, as explained in my answer from the following post: