NoSQL 데이터베이스로 제공되는 FirebaseFirestore에서 Collection 별로 메뉴를 구성하여 보여주다가 메뉴들을 통합하여 보여주는 ALL 메뉴를 새로 구성하여 보여주고 싶다는 생각이 들었다.
그렇다면 어떻게 Collection들을 통합하여 쿼리를 구성할 수 있을까?
일단 2019년 12월 12일 기준으로 최신 버전에 속하는 Firestore 21.0.0 버전에서는 Collection 통합 쿼리 기능을 지원해주지 않는다.
(참고 - https://stackoverflow.com/questions/52944587/firebase-query-collection-and-merge-subcollection-data)
SQL을 사용하면 두 테이블을 조인하여 쉽게 통합 쿼리를 만들 수 있겠으나 NoSQL 기반에서는 자체 기능으로 통합이 힘든 듯하다.
어쩔 수 없이 Firestore의 기능이 아닌, 클라이언트 내의 배열을 사용하여 통합하고 orderBy를 대체하여 Comparator 라이브러리로 정렬까지 성공하였다.
아래는 관련 코드(kotiln 사용)
먼저 정렬할 데이터를 정의할 VO 클래스 생성
import java.io.Serializable
class BaseData : Serializable {
var data1 = 0
var data2 = ""
var time = "" // 정렬에 사용할 변수
}
그 다음 배열에 통합시킬 Collection들을 추가시키고 데이터들을 추출하여 저장한다.
var arrQuery : Array<CollectionReference> = arrayOf()
var listData = ArrayList<BaseData>()
arrQuery = arrQuery.plus(
db.collection("최상위 Collection 이름").document("문서 이름").collection("Collection1")
)
arrQuery = arrQuery.plus(
db.collection("최상위 Collection 이름").document("문서 이름").collection("Collection2")
)
/////////////////////////
//// 데이터 추출 시작
/////////////////////////
for(query in arrQuery) {
(query as Query).get().addOnSuccessListener { result ->
for (document in result) {
var data = BaseData() // VO 객체
data.data1 = document.data.getValue("data1")
data.data2 = document.data.getValue("data2")
data.time = document.data.getValue("time").toString()
listData.add(data) // ArrayList에 저장
}
// 정렬 람다식
listData.sortWith(kotlin.Comparator<BaseData> { baseData1, baseData2 ->
when {
baseData1.time < baseData2.time -> 1
baseData1.time > baseData2.time -> -1
else -> 0
}
})
}
}
이런 식으로 코드를 수행하면 Collection1과 Collection2를 통합하여 time 기준으로 정렬이 완료된 데이터들을 ArrayList에 얻어서 사용할 수 있게 된다.