Firestore search array contains for multiple values
It would be tempting to to look for documents that match multiple conditions, by chaining the conditions in the query:
db.collection("Fruits")
.whereField("vitamins", arrayContains: "B6")
.whereField("vitamins", arrayContains: "C")
But the documentation on compound queries suggests that you cannot currently have multiple arrayContains conditions in a single query.
So, it is not possible with what you have today. Consider instead using a map structure instead of an array:
Fruits:
Banana:
title: "Banana"
vitamins: {
"potassium": true,
"B6": true,
"C": true
}
Then you could query like this:
db.collection("Fruits")
.whereField("vitamins.B6", isEqualTo: true)
.whereField("vitamins.C", isEqualTo: true)
Firestore: Multiple 'array-contains'
Firestore launched another feature similar to the in query, the array-contains-any query. This feature allows you to perform array-contains queries against multiple values at the same time.
ref = ref.where('node_sku' , 'array-contains-any' , list);
Firestore - Array contains any
Firestore array contains query for list of elements
Firestore can now check for these condition on array fields:
- Whether the field contains a specific value with
array-contains
. - Whether the field contains any of a list of (up to 10) values with
array-contains-any
.
What you're describing is an array-contains-all
like operation, which currently doesn't exist. And you can't create it by combining multiple array-contains
checks, as you can only have one of those in a query. You might want to file a feature request for it.
The best option today are to:
- Pick one value from the array, and perform an
array-contains
query with that value. Then you do the additional filtering in your application code. - Use a map to store the values, and then use multiple
where value == true
conditions, as shown in the answer to this question: Firestore: Multiple 'array-contains'
Firestore query - array contains all
As long as you are working with list type fields as you are now, there isn't going to be a way to query that you would find efficient. If you copy the data into a new map type field, it will be possible.
facilities: {
'kettle': true
'microwave': true
'cooker': true
}
With this map containing known boolean values, you can query like this:
firestore
.collection("your-collection")
.where("facilities.kettle", "==", true)
.where("facilities.microwave", "==", true)
.where("facilities.cooker", "==", true)
How to query a firestore array with multiple key value pairs in Swift
You can pass the entire object in an array-contains
clause.
So something like:
usersRef
.whereField("groupMembership", arrayContains: [
"groupId": "kmDT8OUOTCxSMIBf9yZC",
"groupName": "Jon and Charles Group",
"membershipStatus": "pending",
])
The array item must completely and exactly match the dictionary you pass in. If you want to filter only on some of the properties in each array element, you will have to create additional fields with just those properties. For example, it is quite common to have say a field groupIds
with just the (unique) group Ids, so that you can also filter on those (of course within the limits of Firestore's queries).
Related Topics
Difference Between Flatmap and Compactmap in Swift
Segue from Modal View to Tab Bar View Controller and Not Lose Tab Bar
How to Easily Duplicate/Copy an Existing Realm Object
Swift Structs to Nsdata and Back
Using "If Let..." With Many Expressions
How to Use Instance Method as Callback For Function Which Takes Only Func or Literal Closure
Swift Generic Coercion Misunderstanding
How Does String Substring Work in Swift
Wait Until Swift For Loop With Asynchronous Network Requests Finishes Executing
Getting a "This Application Is Modifying the Autolayout Engine from a Background Thread" Error
Detect When a Tab Bar Item Is Pressed
How to Unwrap Double Optionals
How to Use Attributed String in Swiftui