[firebase] Firestore 쿼리 하위 컬렉션

새로운 Firebase Firestore로 하위 컬렉션을 쿼리 할 수 ​​있다고 읽었지만 예제가 보이지 않습니다. 예를 들어 다음과 같은 방식으로 Firestore를 설정했습니다.

  • 춤 [컬렉션]
    • danceName
    • 노래 [컬렉션]
      • 노래 제목

“SongName == ‘X’인 모든 춤 찾기”를 쿼리하려면 어떻게해야합니까?



답변

업데이트 2019-05-07

오늘 우리는 컬렉션 그룹 쿼리를 출시 했으며이를 통해 하위 컬렉션 을 쿼리 할 수 ​​있습니다.

예를 들어 웹 SDK에서 :

db.collectionGroup('Songs')
  .where('songName', '==', 'X')
  .get()

컬렉션 경로의 마지막 부분이 ‘Songs’인 모든 컬렉션의 문서와 일치합니다.

원래 질문은 songName == ‘X’인 댄스 를 찾는 것이 었지만 여전히 직접 불가능하지만 일치하는 각 노래에 대해 부모를로드 할 수 있습니다.

원래 답변

이것은 아직 존재하지 않는 기능입니다. 이를 “컬렉션 그룹 쿼리”라고하며 어떤 댄스에 포함되었는지에 관계없이 모든 노래를 쿼리 할 수 ​​있습니다. 이것은 우리가 지원하려는 것이지만 그것이 언제 올 것인지에 대한 구체적인 일정이 없습니다.

이 시점에서 대체 구조는 노래를 최상위 컬렉션으로 만들고 노래가 노래 속성의 일부인 댄스를 만드는 것입니다.


답변


지금 업데이트 Firestore는 어레이 포함을 지원합니다.

이 문서를 가지고

    {danceName: 'Danca name 1', songName: ['Title1','Title2']}
    {danceName: 'Danca name 2', songName: ['Title3']}

이렇게 해

collection("Dances")
    .where("songName", "array-contains", "Title1")
    .get()...

@ Nelson.b.austin firestore에는 아직 해당 기능이 없으므로 평평한 구조를 갖는 것이 좋습니다.

Dances = {
    danceName: 'Dance name 1',
    songName_Title1: true,
    songName_Title2: true,
    songName_Title3: false
}

그렇게하면 다음과 같이 할 수 있습니다.

var songTitle = 'Title1';
var dances = db.collection("Dances");
var query = dances.where("songName_"+songTitle, "==", true);

이게 도움이 되길 바란다.


답변

노래를 컬렉션이 아닌 개체로 저장하면 어떨까요? 노래를 필드로 사용하여 각 춤 : 유형 Object (컬렉션 아님)

{
  danceName: "My Dance",
  songs: {
    "aNameOfASong": true,
    "aNameOfAnotherSong": true,
  }
}

그런 다음 aNameOfASong으로 모든 댄스를 쿼리 할 수 ​​있습니다.

db.collection('Dances')
  .where('songs.aNameOfASong', '==', true)
  .get()
  .then(function(querySnapshot) {
    querySnapshot.forEach(function(doc) {
      console.log(doc.id, " => ", doc.data());
    });
   })
   .catch(function(error) {
     console.log("Error getting documents: ", error);
    });


답변

2019 업데이트

Firestore는 컬렉션 그룹 쿼리를 출시했습니다. 위의 Gil의 답변 또는 공식 컬렉션 그룹 쿼리 문서를 참조하십시오.


이전 답변

Gil Gilbert가 말했듯이 컬렉션 그룹 쿼리 가 현재 작업중인 것처럼 보입니다 . 그동안 루트 레벨 컬렉션을 사용하고 문서 UID를 사용하여 이러한 컬렉션 사이를 연결하는 것이 더 좋습니다.

아직 모르는 사람들을 위해 Jeff Delaney는 AngularFirebase 에서 Firebase (및 Angular)로 작업하는 모든 사람을위한 놀라운 가이드와 리소스를 제공 합니다.

Firestore NoSQL 관계형 데이터 모델링 -여기서 그는 NoSQL 및 Firestore DB 구조화의 기본 사항을 분석합니다.

Firestore를 사용한 고급 데이터 모델링 (예제 별) -염두에 두어야 할 고급 기술입니다. Firestore 기술을 한 단계 더 높이고 자하는 사람들을위한 훌륭한 책


답변

2019 년 7 월 8 일 새로운 업데이트 :

db.collectionGroup('Songs')
  .where('songName', isEqualTo:'X')
  .get()


답변

항상 다음과 같이 검색 할 수 있습니다.

this.key$ = new BehaviorSubject(null);

return this.key$.switchMap(key =>
  this.angFirestore
    .collection("dances").doc("danceName").collections("songs", ref =>
      ref
        .where("songName", "==", X)
    )
    .snapshotChanges()
    .map(actions => {
      if (actions.toString()) {
        return actions.map(a => {
          const data = a.payload.doc.data() as Dance;
          const id = a.payload.doc.id;
          return { id, ...data };
        });
      } else {
        return false;
      }
    })
);


답변

쿼리 제한

Cloud Firestore는 다음 유형의 쿼리를 지원하지 않습니다.

  1. 다른 필드에 범위 필터가있는 쿼리.

  2. 여러 컬렉션 또는 하위 컬렉션에 대한 단일 쿼리. 각 쿼리는 단일 문서 모음에 대해 실행됩니다. 데이터 구조가 쿼리에 미치는 영향에 대한 자세한 내용은 데이터 구조 선택을 참조
    하십시오 .

  3. 논리적 OR 쿼리. 이 경우 각 OR 조건에 대해 별도의 쿼리를 만들고 앱에서 쿼리 결과를 병합해야합니다.

  4. ! = 절이있는 쿼리. 이 경우 쿼리를보다 큼 쿼리와보다 작음 쿼리로 분할해야합니다. 예를 들어 where ( “age”, “! =”, “30”) 쿼리 절이 지원되지 않더라도 두 쿼리를 where ( “age”, “<) 절과 결합하여 동일한 결과 집합을 얻을 수 있습니다. “,”30 “) 및 where (“age “,”> “, 30) 절이있는 하나.