iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 23
0
Modern Web

我或許沒那麼懂 Web系列 第 23

Cloud Firestore β (15): 進階查詢 - 2

昨天只聊到 where()order()limit(),今天就來把剩下四個方法研究玩吧。而這四個方法的用途也很類似,一起講倒也剛好。一樣先把這四個方法的簽署式和用途列出來:

  • startAt(snapshotOrVarArgs) returns firebase.firestore.Query
  • endAt(snapshotOrVarArgs) returns firebase.firestore.Query
  • startAfter(snapshotOrVarArgs) returns firebase.firestore.Query
  • endBefore(snapshotOrVarArgs) returns firebase.firestore.Query
  • startAt():從指定的 DocumentSnapshot 、或是指定欄位的某個數值後(含)開始獲取資料。
  • endAt():從指定的 DocumentSnapshot 、或是指定欄位的某個數值前(含)開始獲取資料。
  • startAfter():從指定的 DocumentSnapshot 、或是指定欄位的某個數值後(不含)開始獲取資料。
  • endBefore():從指定的 DocumentSnapshot 、或是指定欄位的某個數值前(不含)開始獲取資料。

這四個方法的參數都一樣,可以是 Document Snapshot 也可以是作為排序索引欄位的資料型別的值。差別在於包含該 Snapshot 或是數值與否,以及是從該 Snapshot 或是數值開始,或是到該 Snapshot 或是數值結束。

一樣以城市的人口數為例好了,假設我們有以下資料,為了方便解釋我已經按照人口數去預設排列了:

City | Population
A    | 10000
B    | 20000
C    | 30000
D    | 40000
E    | 50000
F    | 50000
G    | 60000
H    | 60000
I    | 70000
J    | 70000

先做個簡單的例子:

// 回傳 D ~ J
db.collection('cities').order('population', asc).startAt(40000)

// 回傳 C ~ J
db.collection('cities').order('population', asc).startAfter(40000)

// 回傳 A ~ D
db.collection('cities').order('population', asc).endAt(40000)

// 回傳 A ~ C
db.collection('cities').order('population', asc).endBefore(40000)

若是加上 limit()

// 回傳 D、E
db.collection('cities').order('population', asc).startAt(40000).limit(2)

// 回傳 E、F
db.collection('cities').order('population', asc).startAfter(40000)

// 回傳 A、B
db.collection('cities').order('population', asc).endAt(40000)

// 回傳 A、B
db.collection('cities').order('population', asc).endBefore(40000)

若是 startend 混用:

// 回傳 C、H
db.collection('cities').order('population', asc).startAt(3000).endAt(6000)

若是使用 Snapshot 作為參數

// 回傳 H ~ J
db.collection('cities').order('population', asc).startAt(hCityRef)

// 回傳 A ~ H
db.collection('cities').order('population', asc).endAt(hCityRef)

簡單的分頁實作:

let limit = 3
let citiesRef = db.collection('cities').order('population', asc)
let citiesQuery
let cursor
let pageIndex = 1
let paginate = (querySnapshot) => {
  if (querySnapshot.size === 0) {
    cursor = null
    return
  }

  console.log('Page: ' + pageIndex)
  querySnapshot.forEach(citySnapshot => {
    let city = citySnapshot.data()
    console.log(city.name, ' => ', city.poplation)
  })

	cursor = citySnapshots.docs[citySnapshots.size - 1]
  pageIndex += 1
  }
}

citiesQuery = db.collection('cities').order('population', asc).limit(3)
citiesQuery.get().then(paginate)
while (cursor !== null) {
  citiesQuery.startAfter(cursor).get().then(paginate)
}

上一篇
Cloud Firestore β (14): 進階查詢 - 1
下一篇
Cloud Firestore β (16): Transactions
系列文
我或許沒那麼懂 Web31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言