programing

하위 항목에 값이 포함되어 있는지 여부를 Firebase 쿼리

lovejava 2023. 7. 18. 21:23

하위 항목에 값이 포함되어 있는지 여부를 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