iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 22
1
Modern Web

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

Cloud Firestore β (14): 進階查詢 - 1

在第 19 天的 Cloud Firestore β - 11 研究了簡單的查詢概念,今天就來研究比較進階的查詢方法吧!首先看到昨天學到的 Query 提供的數個查詢方法:

  • where(fieldPath, opStr, value) returns firebase.firestore.Query
  • orderBy(fieldPath, directionStr) returns firebase.firestore.Query
  • limit(limit) returns firebase.firestore.Query
  • startAt(snapshotOrVarArgs) returns firebase.firestore.Query
  • endAt(snapshotOrVarArgs) returns firebase.firestore.Query
  • startAfter(snapshotOrVarArgs) returns firebase.firestore.Query
  • endBefore(snapshotOrVarArgs) returns firebase.firestore.Query

這幾個方法分別是用來:

  • where():透過條件去篩選集合中的文件。
  • orderBy():將得到的資料依照指定欄位進行排序。
  • limit():最多拿到幾份資料。
  • startAt():從指定的 DocumentSnapshot 、或是指定欄位的某個數值後(含)開始獲取資料。
  • endAt():從指定的 DocumentSnapshot 、或是指定欄位的某個數值前(含)開始獲取資料。
  • startAfter():從指定的 DocumentSnapshot 、或是指定欄位的某個數值後(不含)開始獲取資料。
  • endBefore():從指定的 DocumentSnapshot 、或是指定欄位的某個數值前(不含)開始獲取資料。

前面三個還好理解,後面四個就有點不太懂了。沒事,就讓我們透過編寫程式碼去一個個暸解吧。

where()

還記得我們在第 15 天裡的 Cloud Firestore β - 7 裡談到各個欄位的資料型別嗎?在介紹各個資料型別時有提到他們的排序方式,也就是所謂的優先大小的概念。而在 where() 的第二個參數,就是運算子 <<===>>=,在使用有大小於的比較,就是用那篇提到的排序方式去做比較的。但儘管暸解了這個概念,在非數值的條件篩選,應該還是 == 的使用情境比較多囉。

let citiesRef = db.collection('cities')

// String `==`
citiesRef.where('state', '==', 'CA')

// Boolean `==`
citiesRef.where('capital', '==', true)

// Number comparison
citiesRef.where('population', '>=', 100000)

// Array
citiesRef.where('districts', 'array-contains', 'west')

至於使用多個 where() 的方式是可以的,這時候都會被當作 AND WHERE 的概念去篩選,在 Cloud Firestore 並沒有 OR WHERE 的概念。但在使用上要注意這兩點:

  1. 若要將等於運算子 == 與其他的運算子 <<=>>=array-contains 混用時,記得要建立於第 14 天 Cloud Firestore β - 6 所提到的複合索引。
  2. 若要使用範圍篩選 <<=>>= 的話,都只能使用在單個欄位上。可以參見以下範例:
// Good:兩個範圍篩選的運算子都是用在同一個欄位。
citiesRef.where('state', '>=', 'CA').where('state', '<=', 'IN')

// Good:雖然是用在不同欄位,但是範圍篩選的運算子的確也只用在同一個欄位而已。
citiesRef.where('state', '==', 'CA').where('population', '>', 1000000)

// Bad:用了兩個範圍篩選的運算子,且針對的是不同欄位。
citiesRef.where('state', '>=', 'CA').where('population', '>', 100000)

order()

這邊應該就沒什麼懸念了,第一個參數填寫欄位名稱,第二個參數則填寫排序方式,asc 為升序、desc 為降序。

let citiesQuery = db.collection('cities').order('population', 'desc')

limit()

這個我想也很好理解,就是這次拿到的資料筆數。通常會搭配 startAt()endAt()startAfter()endBefore() 去做分頁功能或是分批獲取資料,這部分我們明天來研究。

let topThreePopulationCitiesQuery = db
  .collection('cities')
  .order('population', 'desc')
  .limit(3)

上一篇
Cloud Firestore β (13): API 研究
下一篇
Cloud Firestore β (15): 進階查詢 - 2
系列文
我或許沒那麼懂 Web31

1 則留言

0
若虛
iT邦新手 5 級 ‧ 2018-11-07 16:12:51

2018-11-07 16:12:修正錯誤的標題編號。

我要留言

立即登入留言