昨天只聊到 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)
若是 start
和 end
混用:
// 回傳 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)
}