2016-05-20 25 views
5

Diciamo che ho una struttura come questa:Firebase interrogazione

-users 
    -user1_uid 
    name 
    distance 
    age 

Come dovrei fare una query come (Trova utenti con la distanza < 100 e l'età tra 20 e 25)?

Ho provato il metodo standard

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

M problema è, cioè non sembra essere possibile interrogare più bambino (come combinando età e filtraggio distanza). Qualcosa è cambiato a riguardo rispetto a Firebase qualche mese fa? Filtrarli localmente dopo che la prima query non è un'opzione, credo, in quanto potrebbero esserci potenzialmente migliaia di oggetti.

+0

Cosa hai provato finora? Remember Stack Overflow è qui per aiutarti, non per fare il tuo lavoro per te. –

+0

Cross post. Cerca di mantenere i post in un posto per evitare la duplicazione. [Query/filtro del database] (https://groups.google.com/forum/#!searchin/firebase-talk/queryStartingAtValue$3A/firebase-talk/VUoOBAtzCAo/LoCApvVjFgAJ) – Jay

risposta

8

La mia prima scelta sarebbe quella di eseguire una query per tutti gli utenti tra i 20 ei 25 anni e poi filtrare in codice per quelli con una distanza < 100.

la questione degli stati che filtrano nel codice non è un'opzione, ma ho voluto includerlo per completezza per le situazioni in cui è stato diverse migliaia di nodi o meno:

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

     } 

    }) 
} 

Ora una potenziale risposta super semplice.

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

Si noti che stiamo sfruttando .ChildAdded al posto di .Value così ogni nodo viene letto in uno alla volta - se la distanza non è quello che vogliamo è, possiamo ignorare e passare a quello successivo.

+0

Anche il valore queryStartingValue e queryEndingValue funzionano con valori doppi o solo interi? –

+1

@GoodGameIndustries Firebase conosce NSString, NSNumber, NSDictionary e NSArray (evitare gli array). Vedi [Leggi e scrivi dati] (https://firebase.google.com/docs/database/ios/read-and-write). Quindi funzionerà con qualsiasi cosa tu possa inserire in quei tipi di dati, finché ciò che è, è uno di quei tipi. Detto questo, la risposta è sì, puoi usare .startingAt e .endingAt con doubles, ints, stringhe. – Jay