2017-08-15 38 views
0

我正在編寫將firebase元素附加到數組以執行使用文本字段的簡單搜索的代碼。處理由於Firebase查詢中元素數量較多而導致的內存使用率

該方法的代碼如下:

var filteredEvents = [Event]() 
var eventsArray = [Event]() 
fileprivate func fetchEvents(){ 
    print("Fetching events....") 
    //create a reference to the location in the database that you want to pull from and observe the value there 
    let ref = Database.database().reference().child("events") 
    // this will retur a snapshot with all the data at that location in the database and cast the results as a dictionary for later use 
    ref.observe(.value, with: { (snapshot) in 
     guard let dictionaries = snapshot.value as? [String: Any] else{ 
      return 
     } 
     //does the job of sorting dictionary elements by key and value 
     //displaying the key and each corresponding value 
     dictionaries.forEach({ (key,value) in 
      // print(key, value) 
      //creating an eventDictionary to store the results of previous call 
      guard let eventDictionary = value as? [String: Any] else{ 
       return 
      } 
      //will cast each of the values as an Event based off my included struct 
      //Make sure to create a model it is the only way to have the data in the format you want for easy access 
      let events = Event(currentEventKey: key, dictionary:eventDictionary) 
      // appends that to the dictionary to create the dictionary of events 
      self.eventsArray.append(events) 
     }) 
     // will sort the array elements based off the name 
     self.eventsArray.sort(by: { (event1, event2) -> Bool in 
      return event1.currentEventName.compare(event2.currentEventName) == .orderedAscending 
     }) 
     // will again reload the data 
     self.collectionView?.reloadData() 

    }) { (err) in 
     print("Failed to fetch events for search") 
    } 
} 

我個人不認爲,我可能有事件的大量的機會。我無法將所有1000多個活動附加到字典中。這會刺激我的記憶力。無論如何,我可以讓查詢響應文本字段。也可以任何人也許可以幫助我的查詢行將執行此操作,但不會破壞我的記憶?

"events" : { 
"CCDS" : { 
    "attend:count" : 1, 
    "event:date" : { 
    "end:date" : "08/09/2017", 
    "end:time" : "7:00 PM", 
    "start:date" : "08/09/2017", 
    "start:time" : "5:00 PM" 
    }, 
    "event:description" : "Happy hour is more joyful in the summer thanks to Center City District Sips, which offers discounted drinks and appetizers every Wednesday evening. Catch up with old friends and make a few new ones as Center City’s best bars and restaurants host the summer’s happiest hour every Wednesday from 5-7 p.m. Enjoy $5 cocktails, $4 wine, $3 beers and half-price appetizers at dozens and dozens of bars and restaurants.", 
    "event:imageURL" :someURL", 
    "event:location" : { 
    "event:city" : "Philadelphia", 
    "event:state" : "PA", 
    "event:street:address" : "660 Chestnut St", 
    "event:zip" : 19106 
    }, 
    "event:name" : "Center City District Sips" 
}, 
"MIA" : { 
    "attend:count" : 1, 
    "event:date" : { 
    "end:date" : "09/03/2017", 
    "end:time" : "7:00 PM", 
    "start:date" : "09/02/2017", 
    "start:time" : "12:00 PM" 
    }, 
    "event:description" : "Budweiser Made in America Festival is an annual music festival held in Philadelphia and formerly simultaneously held in Los Angeles.Sponsored by Anheuser–Busch and produced by Live Nation, the event features several stages that continuously host live music from a wide range of genres including hip hop, rock, pop, R&B, and EDM.", 
    "event:imageURL" : "someURL", 
    "event:location" : { 
    "event:city" : "Philadelphia", 
    "event:state" : "PA", 
    "event:street:address" : "Ben Franklin Parkway", 
    "event:zip" : 19130 
    }, 
    "event:name" : "Made In America" 
} 
    }, 

例如,我想提取有關使用查詢搜索的事件的所有信息。所以,如果我開始輸入美國製造它會拉動有關事件從事件選項卡中的所有相關信息

這是我目前有

fileprivate func fetchEvents(searchString: String){ 
    print("Fetching events....") 
    //create a reference to the location in the database that you want to pull from and observe the value there 
    let ref = Database.database().reference().child("events") 
    // this will retur a snapshot with all the data at that location in the database and cast the results as a dictionary for later use 
    let query = ref.queryOrdered(byChild: "event:name").queryEqual(toValue: searchString) 
    print(query) 
    query.observeSingleEvent(of: .value, with: { (snapshot) in 
     guard let dictionary = snapshot.value as? [String: Any] else{ 
      print(snapshot.value) 
      return 
     } 
     print(snapshot.value) 
    }) { (err) in 
     print("Failed to fetch event data", err) 
    } 

} 

返回此

(/events { ep = Made In America; i = "event:name"; sp = Made In America; })

+1

爲了澄清,你問有一種方法可以讓textField在其中輸入一些值,然後查詢數據庫以查找該值?或者你是否想要做一些類似無限滾動的操作,一次只下載幾個孩子? –

+0

@JenPerson即時通訊尋找一種方式,讓我有一個文本框,我輸入一些價值,然後quesry尋找該值的firebase – SJackson5

+0

通知每個用戶已問/編輯你的問題是不是很好。請耐心等待,因爲這是一個問答社區,而不是付費支持論壇。請參閱SO的[「保持良好」政策](https://stackoverflow.com/help/be-nice)。 – nathan

回答

1

看來問題是

"How can I query for a value contained in a child node?" 

給定的結構類似於原始

"events" : { 
    "CCDS" : { 
    "attend:count" : 1, 
    "event:imageURL" :"someURL", 
    "event:name" : "Center City District Sips" 
    "MIA" : { 
    "attend:count" : 1, 
    "event:imageURL" : "someURL", 
    "event:name" : "Made In America" 

一個火力地堡查詢將返回你想要的節點。

如果用戶輸入美國製造並點擊搜索按鈕,查詢將在快照中返回該節點。

let searchString = "Made In America" 
let ref = self.ref.child("events") 
let query = ref.queryOrdered(byChild: "event:name").queryEqualTo(searchString) 
query.observeSingleEvent(of: .value, with: { (snapshot) in 
    for child in snapshot.children { 
     let snap = child as! DataSnapshot 
     let eventDict = snap.value as! [String: Any] 
     let attendCount = eventDict["attend:count"] as! String 
     let url = eventDict["event:imageURL"} as! String 
    } 
}) 

如果你想要做一個局部的字符串匹配,用戶可以輸入在短短的字符,如製造的代碼是相似的,但你需要讓火力返回所有開始進行的比賽。 ..

查詢應該是這樣的

let startString = "Made" 
let endString = "Made" + "\\uf8ff" 
let query = ref.queryOrdered(byChild: "event:name") 
         .queryStarting(atValue: startString) 
         .queryEnding(atValue: endString") 

的「\ uf8ff」是在Unicode的一個非常高的代碼級人物 - 因爲它包含了所有的前述字符。

但是,「即時」查詢可能會導致無響應或緩慢的UI,因此不推薦使用。

另一種方法是創建一個單獨的節點,其中包含很少的信息幷包含用戶將搜索的元素和對事件節點的引用。

因此包含所有數據的主節點看起來像這樣

"events" : { 
    "-uyuh8s8j8jsdas" : { 
    "event": "CCDS" 
    "attend:count" : 1, 
    "event:imageURL" : "someURL", 
    "-y88jsijsijjids" : { 
    "event": "MIA" 
    "attend:count" : 1, 
    "event:imageURL" : "someURL", 

和「小」節點應該是這樣的

events_for_searching 
     -uyuh8s8j8jsdas 
     event:name: "Center City District Sips" 
     -y88jsijsijjids 
     event:name: "Made In America" 

有了這個,你可以加載所有的節點從events_for_searching到一個數組中(然後過濾數組作爲用戶類型),這將使UI非常敏感,當用戶選擇一個名稱時,可以使用該節點中的鍵作爲參考,從事件節點加載數據通過一個observeSingleEvent函數。

編輯

在迴應評論,我想在代碼中添加更多的細節。

這裏是我的結構

"events" : { 
    "event_0" : { 
     "event:name" : "An Event" 
    }, 
    "event_1" : { 
     "event:name" : "Made In America" 
    } 
    }, 

,並查詢事件的代碼:名稱:美國製造

let searchString = "Made In America" 
let ref = self.ref.child("events") 
let query = ref.queryOrdered(byChild: "event:name").queryEqual(toValue: searchString) 

query.observeSingleEvent(of: .value, with: { (snapshot) in 
    guard let dictionary = snapshot.value as? [String: Any] else{ 
     print(snapshot.value) 
     return 
    } 
    print(snapshot.value) 
}) { (err) in 
    print("Failed to fetch event data", err) 
} 

和輸出

Optional({ 
    "event_1" =  { 
     "event:name" = "Made In America"; 
    }; 
}) 
+0

感謝我真的很感激幫助 – SJackson5

+0

看到沒有工作 – SJackson5

+0

林不知道這是什麼意思 (/事件{ EP =蘋果; I = 「事件:名」; SP =蘋果; }) – SJackson5

相關問題