하위 항목에 값이 포함되어 있는지 여부를 Firebase 쿼리
표의 구조는 다음과 같습니다.
- 잡담
- --> 랜덤이드
- -->--> 참가자
- -->-->--> 0: 'name1'
- -->-->--> 1: 'name2'
- -->--> 채팅 항목
기타
전달된 사용자 이름 문자열로 참가자를 고정하는 모든 대화를 찾기 위해 대화 테이블을 쿼리하려고 합니다.
지금까지 제가 가진 것은 다음과 같습니다.
subscribeChats(username: string) {
return this.af.database.list('chats', {
query: {
orderByChild: 'participants',
equalTo: username, // How to check if participants contain username
}
});
}
현재 데이터 구조는 특정 대화의 참가자를 검색하기에 좋습니다.그러나 사용자가 참여하는 대화라는 역방향을 찾기에는 그다지 좋은 구조가 아닙니다.
여기에 몇 가지 문제가 있습니다.
- 집합을 배열로 저장하고 있습니다.
- 고정 경로에서만 인덱싱할 수 있습니다.
세트 대 어레이
대화에는 여러 명의 참가자가 있을 수 있으므로, 이 대화를 배열로 모델링했습니다.하지만 이것은 실제로 이상적인 데이터 구조가 아닙니다.각 참가자는 대화에 한 번만 참여할 수 있습니다.하지만 어레이를 사용하면 다음과 같은 이점을 얻을 수 있었습니다.
participants: ["puf", "puf"]
그것은 분명히 여러분이 생각하고 있는 것이 아니지만, 데이터 구조는 그것을 허용합니다.코드 및 보안 규칙에서 이를 보호할 수 있지만 모델과 암묵적으로 더 잘 일치하는 데이터 구조로 시작하는 것이 더 쉽습니다.
제 경험의 법칙: 만약 여러분이 글을 쓰고 있다면, 여러분은 세트를 사용해야 합니다.
세트는 각 자식이 한 번에 있을 수 있는 구조이므로 중복으로부터 자연스럽게 보호합니다.Firebase에서 세트를 다음과 같이 모델링할 수 있습니다.
participants: {
"puf": true
}
그true
여기에는 정말 더미 값이 있습니다. 중요한 것은 우리가 키로 이름을 옮겼다는 것입니다.제가 이 채팅에 다시 참여하려고 한다면, 그것은 바보가 될 것입니다.
participants: {
"puf": true
}
그리고 당신이 합류할 때:
participants: {
"john": true,
"puf": true
}
이것은 각 참가자를 한 번만 포함할 수 있는 모음입니다.
알려진 속성만 인덱싱할 수 있습니다.
위의 구조를 사용하여 다음과 같은 대화를 쿼리할 수 있습니다.
ref.child("chats").orderByChild("participants/john").equalTo(true)
문제는 이를 위해 '참가자/존'에 대한 인덱스를 정의해야 한다는 것입니다.
{
"rules": {
"chats": {
"$chatid": {
"participants": {
".indexOn": ["john", "puf"]
}
}
}
}
}
이것은 효과적이고 훌륭한 성능을 발휘할 것입니다.그러나 이제 새로운 사용자가 채팅 앱에 가입할 때마다 다른 인덱스를 추가해야 합니다.그것은 분명히 확장 가능한 모델이 아닙니다.원하는 쿼리를 허용하도록 데이터 구조를 변경해야 합니다.
색인 반전 - 범주를 위로 끌어 트리를 평평하게 만듭니다.
두 번째 경험칙: 앱에 표시된 내용을 반영하도록 데이터를 모델링합니다.
사용자의 대화방 목록을 표시하려고 하므로 각 사용자의 대화방을 저장합니다.
userChatrooms: {
john: {
chatRoom1: true,
chatRoom2: true
},
puf: {
chatRoom1: true,
chatRoom3: true
}
}
이제 다음을 사용하여 대화방 목록을 쉽게 결정할 수 있습니다.
ref.child("userChatrooms").child("john")
그리고 열쇠를 돌려 각 방을 확보합니다.
앱에 두 개의 관련 목록이 있습니다.
- 특정 사용자에 대한 대화방 목록
- 특정 대화방의 참가자 목록
이 경우 데이터베이스에 두 개의 목록도 있습니다.
chatroomUsers
chatroom1
user1: true
user2: true
chatroom2
user1: true
user3: true
userChatrooms
user1:
chatroom1: true
chatroom2: true
user2:
chatroom1: true
user2:
chatroom2: true
두 목록을 모두 트리의 최상위 수준으로 끌어올렸습니다. Firebase에서 중첩 데이터에 대해 권장하기 때문입니다.
NoSQL 솔루션에서는 두 개의 목록을 모두 갖는 것이 완전히 정상입니다.위의 예에서 우리는 다음을 참조할 것입니다.userChatrooms
으로의 로서.chatroomsUsers
.
클라우드 파이어스토어
이는 Cloud Firestore가 이러한 유형의 쿼리를 더 잘 지원하는 경우 중 하나입니다.그것의.array-contains
수 있도록 , operator는 문서를 필터링할 수 있습니다.arrayRemove
배열을 집합으로 처리할 수 있습니다.자세한 내용은 Cloud Firestore의 향상된 어레이를 참조하십시오.
언급URL : https://stackoverflow.com/questions/40656589/firebase-query-if-child-of-child-contains-a-value
'programing' 카테고리의 다른 글
Python(또는 불변 데이터 유형)에서 튜플이 필요한 이유는 무엇입니까? (0) | 2023.07.18 |
---|---|
Matlab의 tic 및 toc 함수에 해당하는 파이썬은 무엇입니까? (0) | 2023.07.18 |
ASP.NET 코어에서 Swagger의 기본 URL을 변경하는 방법 (0) | 2023.07.18 |
장고 앱을 완전히 제거하는 방법은 무엇입니까? (0) | 2023.07.18 |
대용량 데이터에서 NA를 가장 빠르게 대체할 수 있는 방법.표 (0) | 2023.07.18 |