2016-05-20 10 views
5

Lassen Sie uns sagen, ich habe eine Struktur wie folgt aus:Firebase Abfrage

-users 
    -user1_uid 
    name 
    distance 
    age 

Wie würde ich tun, eine Abfrage wie (Finden Benutzer mit Abstand < 100 und das Alter zwischen 20 und 25)?

Ich habe die Standard-Methode versucht

 let recentPostsQuery = (ref?.child("users").queryOrderedByChild("age").queryStartingAtValue("20"))! 

M Problem ist, das heißt nicht erscheint möglich zu sein, mehrere Childs abzufragen (wie Alter und Entfernung Filterungs Combining). Hat sich diesbezüglich vor ein paar Monaten etwas gegen Firebase geändert? Es ist keine Option, sie nach der ersten Abfrage lokal zu filtern, da es möglicherweise Tausende von Objekten geben könnte.

+0

Was haben Sie bisher versucht? Denken Sie daran, Stack Overflow ist hier, um Ihnen zu helfen, nicht Ihre Arbeit für Sie zu tun. –

+0

Querpfosten. Versuchen Sie, die Posts an einem Ort zu behalten, um Doppelarbeit zu vermeiden. [Datenbankabfrage/Filterung] (https://groups.google.com/forum/#!searchin/firebase-talk/queryStartingAtValue$3A/firebase-talk/VUoOBAtzCAo/LoCApvVjFgAJ) – Jay

Antwort

8

Meine erste Wahl für alle Nutzer zwischen 20 und 25 und dann für diejenigen in Code filtern, um abzufragen, wäre mit ein Abstand < 100.

Die Zustände Frage Code Filterung ist keine Option, aber ich wollte es auf Vollständigkeit für Situationen umfassen, in denen es mehrere tausend Knoten oder weniger war:

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!)") 

     } 

    }) 
} 

Jetzt eine mögliche super einfache Antwort.

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)") 
     } 
    }) 

Beachten Sie, dass wir statt .Wert .ChildAdded sind Hebelwirkung, so dass jeder Knoten in einem nach dem anderen lesen - wenn der Abstand nicht ist, was wir wollen, können wir es ignorieren können und zum nächsten bewegen.

+0

Funktioniert der queryStartingValue und queryEndingValue auch mit doppelten Werten? oder nur ganze Zahlen? –

+1

@GoodGameIndustries Firebase kennt NSString, NSNumber, NSDictionary und NSArray (bitte vermeiden Sie Arrays). Siehe [Daten lesen und schreiben] (https://firebase.google.com/docs/database/ios/read-and-write). Es funktioniert also mit allem, was Sie in diese Datentypen einfügen können, solange es sich um einen dieser Typen handelt. Das heißt, die Antwort ist ja, Sie können. StartingAt und .endingAt mit Doppel, Ints, Strings verwenden. – Jay