2017-07-25 25 views
0

我的數據結構如下:分頁中具有相同的孩子火力值

users: 
    user1: 
    -carModel: evo x 
    -username: importguy 
    -region: north east 
    user2: 
    -carModel: evo x 
    -username: evoguy 
    -region: north east 
    user3: 
    -carModel: mustang gt 
    -username: muscleguy 
    -region: south east 

我希望用戶能夠搜索車,說EVO,以及用戶的顯示結果誰擁有這些特殊汽車。我需要爲我的應用分頁這些結果。問題是我無法弄清楚如何正確地查詢這個。這是我到目前爲止。

func fetchUsersBy(car: String) { 

    if self.carCurrentKey == nil { 

     let ref = USER_REF.queryOrdered(byChild: "carModel").queryStarting(atValue: car).queryLimited(toFirst: 3) 

     ref.observeSingleEvent(of: .value, with: { (snapshot) in 

      guard let snap = snapshot.children.allObjects as? [FIRDataSnapshot] else { return } 
      guard let last = snapshot.children.allObjects.last as? FIRDataSnapshot else { return } 

      snap.forEach({ (snapshot) in 

       guard let userDict = snapshot.value as? Dictionary<String, AnyObject> else { return } 
       guard let carModel = userDict["carModel"] as? String else { return } 

       if carModel.contains(car) { 
        print(snapshot) 
       } 
      }) 
      self.carCurrentKey = last.key 
      self.carCurrentValue = last.childSnapshot(forPath: "carModel").value as? String 
     }) 
    } else { 
     // where to start next query? 
     let ref = USER_REF.queryOrder(byChild: "carModel").queryStarting(atValue: self.carCurrentValue) 
    } 
} 

我必須通過carModel命令查詢,以便將具有該特定車型的所有用戶分組到一個快照中。由於所有的車型都是相同的價值,我無法弄清楚分頁的下一個查詢開始或結束的位置。使用我在else塊中的引用在與上述塊相同的位置開始查詢。任何幫助或建議將不勝感激。

我認爲是做了一個扇子,併爲汽車類型製作了一個單獨的結構。這將是困難的,但。

回答

1

對於startAt()和endAt(),您都可以傳遞第二個值childKey,如here所示。

所以您的查詢就會是這個樣子:

let ref = USER_REF.queryOrdered(byChild: "carModel").queryStarting(atValue: self.carCurrentValue, childKey: self.carCurrentKey).queryLimited(toFirst: 3+1) 

請注意,我用toFirst: 3+1。這是因爲,惱人的是,startAt()是包容性的,沒有辦法跳過第一條記錄。因此,由於我們從上一頁上的最後一條記錄開始,您將需要查詢一條額外的記錄並放棄第一條結果。

下面是JavaScript中更完整的示例。不夠熟悉將其轉換爲Swift,但它應該爲您提供完成算法。

class Cursor { 
    constructor(baseRef, pageSize) { 
     this.baseRef = baseRef; 
     this.lastKey = null; 
     this.lastValue = null; 
     this.pageSize = pageSize; 
    } 

    next() { 
    let ref = this.baseRef; 

    if(this.lastValue !== null) { 
     // a previous page has been loaded so get the next one using the previous value/key 
     // we have to start from the current cursor so add one to page size 
     ref = ref.startAt(this.lastValue, this.lastKey).limitToFirst(this.pageSize+1); 
    } 
    else { 
     // this is the first page 
     ref = ref.limitToFirst(this.pageSize); 
    } 

    return ref.once('value').then(snap => { 
     const keys = []; 
     const data = []; // store data in array so it's ordered 

     snap.forEach(ss => { 
      data.push(ss.val()); 
      keys.push(ss.key); 
     }); 

     if(this.lastValue !== null) { 
     // skip the first value, which is actually the cursor 
     keys.shift(); 
     data.shift(); 
     } 

     // store the last loaded record 
     if(data.length) { 
     const last = data.length - 1; 
     this.lastKey = keys[last]; 
     this.lastValue = data[last].author; 
     } 

     return data; 
    }); 
    } 
} 

and here's a working fiddle

請記住,這是一個實時數據流。所以分頁是棘手的。做一個無限滾動通常比在一個移動的數據集上嘗試和維護一個真實的光標更容易(記錄可以在數據改變,被刪除,添加在中間等時重新排序)。

+0

看起來像它的工作原理,但無論如何,你可以在swift中發佈解決方案嗎? – Dirty

+0

答案是在您的startAt()調用中使用childKey。剩下的只是獎金,可以幫助您瞭解下一步將要走向何方。 – Kato

+0

謝謝!答案接受! – Dirty

相關問題