2016-05-20 3 views
5

Скажем, у меня есть структура вроде этого:Firebase запрашивая

-users 
    -user1_uid 
    name 
    distance 
    age 

Как бы я сделать запрос типа (Найти пользователей с расстоянием < 100 и возраст от 20 до 25 лет)?

Я попробовал стандартный метод

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

М проблема в том, что это не представляется возможным, чтобы запросить несколько Childs (как объединение возраста и расстояния фильтрации). Что-то изменилось в этом отношении по сравнению с Firebase несколько месяцев назад? Я считаю, что фильтрация их локально после первого запроса не является вариантом, поскольку потенциально могут быть тысячи объектов.

+0

Что вы пробовали? Помните, что Stack Overflow здесь, чтобы помочь вам, а не делать вашу работу за вас. –

+0

Перекресток. Попытайтесь сохранить сообщения в одном месте, чтобы предотвратить дублирование. [Запрос/фильтрация базы данных] (https://groups.google.com/forum/#!searchin/firebase-talk/queryStartingAtValue$3A/firebase-talk/VUoOBAtzCAo/LoCApvVjFgAJ) – Jay

ответ

8

Мой первый выбор будет запрашивать для всех пользователей в пределах от 20 до 25 лет, а затем процеживают в коде для тех, с расстояние < 100.

вопросительные состояния фильтрации в коде не вариант, но я хотел бы включить его для полноты для ситуаций, когда это было несколько тысяч узлов или менее:

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

     } 

    }) 
} 

Теперь потенциальный супер простой ответ.

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

Обратите внимание, что мы Усиливая .ChildAdded вместо .Value, так что каждый узел считывается по одному за раз - если расстояние не то, что мы хотим, мы можем игнорировать его и двигаться дальше к следующему.

+0

Будет ли работать с queryStartingValue и queryEndingValue с двойными значениями или просто целые числа? –

+1

@GoodGameIndustries Firebase знает о NSString, NSNumber, NSDictionary и NSArray (пожалуйста, избегайте массивов). См. [Чтение и запись данных] (https://firebase.google.com/docs/database/ios/read-and-write). Таким образом, он будет работать со всем, что вы можете поместить в эти типы данных, до тех пор, пока что бы то ни было, является одним из этих типов. При этом ответ да, вы можете использовать .startingAt и .endingAt с удвоениями, ints, string. – Jay

Смежные вопросы