[golang] Firestore의 Document를 다양한 방법으로 쿼리

7268 단어 5Firestore
이 기사는 Voicy Advent Calendar 2020의 25 일째 기사입니다.
전날은 @saicologic씨의 엔지니어의 일과 죽음에 게임과 나 였습니다.

소개



먼저, 하고 싶은 일로, 여러 문서를 한번에 ID로 취득하고 싶다고 하는 목표가 있어, 그 목표를 달성하기까지 여러가지 시도한 쿼리를 기록해 갑니다.
전제조건으로, 검색하려는 문서의 ID가 자동으로 생성되고 검색하려는 문서의 ID가 손에 있고 배열에 있다고 가정합니다.

자동 생성된 문서 ID를 사용하는 동기



Cloud Firestore 모범 사례 에 의하면, 비연속의 자동 생성된 ID를 사용하는 것이 좋다고 하는 것입니다.



1. 하나의 문서 얻기



우선은 기본으로 돌아와서, 하나의 문서의 취득 방법에 대해 생각합니다.
자동 생성된 ID를 가진 문서에서도 하나만 있으면 간단하게 얻을 수 있습니다.
취득하고 싶은 문서의 ID와 컬렉션명을 알고 있으면 아래와 같은 쿼리로 취득할 수 있습니다.

client.Collection("collection-name")
  .Doc("AuTOGEneRatEdID")
  .Get(ctx)

여러 문서 검색(필드에도 ID가 등록되어 있는 경우)



하나의 Document를 얻는 것에 대해 생각했으므로, 다음은 여러 Document를 얻는 방법을 생각합니다.

문서에 필드가 있는 경우 간단히 해당 필드로 쿼리하면 쉽게 원하는 Document를 얻을 수 있습니다. Cloud Firestore에서 간단한 쿼리와 복합 쿼리를 실행합니다(공식 문서).
일본어판의 문서에는 기재가 없지만, 이 페이지의 영어판에는 이하와 같이 기재되어 있습니다. Perform simple and compound queries in Cloud Firestore



위를 참고로 쿼리하면 다음과 같습니다.
client.Collection("collection-name")
  .Where("document_id", "in", documentIds)
  .GetAll(ctx)

다만, Document의 ID(패스로 사용되는 쪽)와 Document의 필드의 ID의 값은 피해 버립니다.

다중 문서 검색 (직접 ID로 쿼리하는 경우)



자동 생성된 ID를 하나의 문서의 필드에 등록하는 것은 별로 하고 싶지 않기 때문에 다른 기법을 생각합니다.

조사해 보면, __name__ 는 사전에 준비된 필드로, 객체의 path 를 돌려준다고 합니다.
그래서, __name__ 에 대해서, 자동 생성되고 있는 ID 를 지정해 주면, 지정의 ID 의 문서를 취득할 수 있습니다. __name__ 는 golang firestore package에서 firestore.DocumentID 로 정의되어 있으므로 사용합니다.
// DocumentID is the special field name representing the ID of a document
// in queries.
const DocumentID = "__name__"

아래와 같이 쿼리합니다. 객체의 경로를 대상으로 하므로 자동 생성된 ID로도 사용할 수 있고, Where구를 사용하고 있으므로, 부등호가 아니어도 'in'도 물론 사용할 수 있습니다.
clinet.Collection("collection-name")
  .Where(
    firestore.DocumentID,
    "in", 
    documentIds
  )
  .GetAll(ctx)

이제 원래 목표대로 Document를 얻을 수 있습니다.

__ name __이 왜 골랑에서 작동하지 않는 문제



그런데 그렇게 잘하지 못하고, python에서도 Nodejs에서도 __ name __을 지정하면 ID로 쿼리 할 수 ​​있지만, Golang에서는 왜 잘 작동하지 않았다 ... (자신의 환경 만일지도) 때문에, 대안 생각합니다.

다중 문서 검색 (직접 ID로 쿼리하는 경우)



수법으로서는, 취득하고 싶은 Document의 ID를 지정해 DocumentRef를 작성해 취득한다고 하는 것.
궁극적으로 다음과 같이 쿼리하여 목적에 따라 여러 ID로 firestore의 Document를 얻을 수있었습니다.

// 取得したいドキュメントを持つCollectionを取得
collectionRef := client.Collection("collection-name")

// 取得したいDocumentのIDを指定して、DocumentRefを作成する
tmpDocs := make([]*firestore.DocumentRef, len(documentIDs))
for idx, id := range documentIDs {
    tmpDocs[idx] = collectionRef.Doc(strconv.FormatInt(id, 10))
}

//DocumentRefを一気に取得する
docs, err := r.firestoreClient.GetAll(ctx, tmpDocs)
if err != nil {
    return err
}


결론



더 좋은 방법이 공식 문서의 어딘가에 제대로 기재되어 있을지도 모른다.
그 경우는 링크를 붙이므로 가르쳐 주세요.

연말까지 좀 더, 여러분, 좋은 해를 맞이해 주세요! !

좋은 웹페이지 즐겨찾기