-
Notifications
You must be signed in to change notification settings - Fork 1
Firestore에서_검색_쿼리_만들기
yujin45 edited this page Nov 25, 2024
·
1 revision
Firestore는 기본적으로 startsWith
와 같은 문자열 검색 기능을 직접 제공하지 않는다. 하지만 문자열의 범위를 설정하는 쿼리를 조합하여 유사한 동작을 구현할 수 있다.
Firestore는 문자열 비교를 사전순으로 처리하며, whereGreaterThanOrEqualTo
와 whereLessThanOrEqualTo
를 조합하여 특정 접두사로 시작하는 항목을 검색할 수 있다.
fireStore.collection("USER")
.whereGreaterThanOrEqualTo("displayName", "Jo")
.whereLessThanOrEqualTo("displayName", "Jo\\uf8ff")
.get()
.await()
-
whereGreaterThanOrEqualTo("Jo")
:displayName
필드가"Jo"
와 같거나 그보다 사전순으로 큰 값만 포함한다. -
whereLessThanOrEqualTo("Jo\\uf8ff")
:displayName
필드가"Jo"
로 시작하는 값 중 가장 큰 범위까지만 포함한다. - 위 두 조건을 조합하면
"Jo"
로 시작하는 값(예:"Jo"
,"John"
,"Johnny"
)만 가져온다.
- Firestore는 문자열 검색에서 대소문자를 구분하므로
"jo"
와"Jo"
는 다른 값으로 인식된다. -
\\uf8ff
는 유니코드 문자 중 가장 큰 값을 나타내며, 문자열 검색의 끝 범위를 설정할 때 사용된다.
fireStore.collection("USER")
.whereGreaterThanOrEqualTo("displayName", "Jo")
.get()
.await()
- 이 쿼리는
displayName
이 "Jo"와 같거나 사전순으로 더 큰 값을 모두 가져옴 - 즉,
"Jo"
,"John"
,"Johnny"
,"Michael"
등이 포함
-
"Jo"
로 시작하지 않는"Michael"
,"Zoe"
와 같은 값도 포함될 수 있음 - 따라서
startsWith
와 동일한 동작이 아니며, 범위를 좁히는 추가 조건이 필요
fireStore.collection("USER")
.whereLessThanOrEqualTo("displayName", "Jo\\uf8ff")
.get()
.await()
- 이 쿼리는
displayName
이"Jo\\uf8ff"
보다 작거나 같은 모든 값을 가져옴 - Firestore에서 문자열은 사전순으로 정렬되므로, "Jo"로 시작하는 항목만 포함.
"Jo"
,"John"
,"Johnny"
는 포함되지만,"Joker"
,"Michael"
등은 포함되지 않음.
- 시작점을 지정하지 않았기 때문에
"Ja"
,"Jack"
과 같은 "Jo"보다 작은 값도 포함될 수 있다.
fireStore.collection("USER")
.whereGreaterThanOrEqualTo("displayName", "Jo")
.whereLessThanOrEqualTo("displayName", "Jo\\uf8ff")
.get()
.await()
- 이 쿼리는
displayName
이 "Jo"로 시작하는 항목만 정확히 검색. -
"Jo"
,"John"
,"Johnny"
는 포함 -
"Joker"
,"Michael"
,"Ja"
등 "Jo"로 시작하지 않는 값은 제외.
-
whereGreaterThanOrEqualTo("Jo")
: "Jo"와 같거나 더 큰 값부터 검색을 시작. -
whereLessThanOrEqualTo("Jo\\uf8ff")
: "Jo"로 시작하는 문자열 범위의 끝을 지정. - 두 조건이 함께 있어야 "Jo"로 시작하는 값만 정확히 포함.
조건 사용 | 동작 설명 | 결과 |
---|---|---|
whereGreaterThanOrEqualTo만 사용 | 시작 범위만 지정, 끝 범위 없음 | "Jo", "John", "Johnny", "Michael" 포함 |
whereLessThanOrEqualTo만 사용 | 끝 범위만 지정, 시작 범위 없음 | "Ja", "Jack", "Jo", "John", "Johnny" 포함 |
둘 다 사용 | 시작과 끝 범위를 모두 지정하여 정확히 startsWith 흉내 냄 | "Jo", "John", "Johnny"만 포함 |
-
startsWith
와 같은 동작 구현하려면 둘 다 필요.
Firestore는 기본적으로 OR
조건을 지원하지 않으므로, 두 개의 쿼리를 별도로 실행한 후 결과를 병합해야 한다.
suspend fun searchUsers(query: String): List<FirestoreUser> {
val displayNameResults = fireStore.collection("USER")
.whereGreaterThanOrEqualTo("displayName", query)
.whereLessThanOrEqualTo("displayName", query + "\\uf8ff")
.get()
.await()
.toObjects(FirestoreUser::class.java)
val emailResults = fireStore.collection("USER")
.whereGreaterThanOrEqualTo("email", query)
.whereLessThanOrEqualTo("email", query + "\\uf8ff")
.get()
.await()
.toObjects(FirestoreUser::class.java)
return (displayNameResults + emailResults).distinctBy { it.uid }
}
-
displayName
필드와email
필드 각각에 대해 검색 쿼리를 실행한다. - 결과를 병합하고, 동일한
uid
값을 가진 중복 항목은 제거한다. - 이를 통해
query
로 시작하는displayName
또는email
필드를 검색할 수 있다.
- 두 개의 쿼리가 실행되므로 네트워크 호출 비용이 늘어난다.
- Firestore 쿼리는 항상 특정 필드에 대해 인덱싱이 필요하다.
- displayName과 email 둘 다 검색할 수 있게 하기 위해서는 위와 같은 방법을 사용할 수 있다.
- 그러나 우선은 우리 기획은 email 기반 검색이기에 email 검색만 구현해보도록 하겠다.
데일리 스크럼
1주차
2주차
3주차
4주차
5주차
회의록
1주차
2주차
3주차
4주차
5주차