Let's say I have a structure like this:
-users
-user1_uid
name
distance
age
How would I do a query like (Find users with distance <100 and age between 20 and 25)?
I have tried the standard method
let recentPostsQuery = (ref?.child("users").queryOrderedByChild("age").queryStartingAtValue("20"))!
M problem is, that is does not appear to be possible to query multiple childs (like combining age and distance filtering). Did something change in this regard compared to Firebase a few months ago? Filtering them locally after the first query is not an option, I believe, as there could be potentially thousands of objects.
A Firebase reference represents a particular location in your Database and can be used for reading or writing data to that Database location. The Query class (and its subclass, DatabaseReference ) are used for reading data. Listeners are attached, and they will be triggered when the corresponding data changes.
If your data model needs something more than a single join query, never choose firebase. It is highly suggested not to choose Firebase for android application if your intended operation is to perform deep and complex querying.
Firebase uses NoSQL; MySQL uses SQL.
My first choice would be to query for all the users between 20 and 25 and then filter in code for ones with a distance < 100.
The question states filtering in code is not an option but I wanted to include it for completeness for situations where it was several thousand nodes or less:
struct User { //starting with a structure to hold user data
var firebaseKey : String?
var theAge: Int?
var theDistance: Int?
}
var userArray = [User]() //the array of user structures
usersRef.queryOrderedByChild("age").queryStartingAtValue(20)
.queryEndingAtValue(25).observeEventType(.Value, withBlock: { snapshot in
for child in snapshot.children { //.Value so iterate over nodes
let age = child.value["age"] as! Int
let distance = child.value["distance"] as! Int
let fbKey = child.key!
let u = User(firebaseKey: fbKey, theAge: age, theDistance: distance)
userArray.append(u) //add the user struct to the array
}
//the array to contain the filtered users
var filteredArray: [User] = []
filteredArray = userArray.filter({$0.theDistance < 100}) //Filter it, baby!
//print out the resulting users as a test.
for aUser in filteredArray {
let k = aUser.firebaseKey
let a = aUser.theAge
let d = aUser.theDistance
print("array: \(k!) \(a!) \(d!)")
}
})
}
Now a potential super simple answer.
let usersRef = self.myRootRef.childByAppendingPath("users")
usersRef.queryOrderedByChild("age").queryStartingAtValue(20)
.queryEndingAtValue(25).observeEventType(.ChildAdded, withBlock: { snapshot in
let distance = snapshot.value["distance"] as! Int
if distance < 100 {
let age = snapshot.value["age"] as! Int
let fbKey = snapshot.key!
print("array: \(fbKey) \(age) \(distance)")
}
})
Notice that we are leveraging .ChildAdded instead of .Value so each node is read in one at a time - if the distance is not what we want, we can ignore it and move on to the next.
Firebase can't combine always the conditions. How to query based on multiple conditions in Firebase?
But, using the new firebase API, this post can give some hints: Query based on multiple where clauses in firebase
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With