Querier

GoでのFirestoreデータ操作完全ガイド | ドキュメントの取得、追加、更新、削除まで

2023.07.10に公開 | 2023.07.10に更新

Querier運営

@querier_io@querierinc

「Querier(クエリア)」は社内向け管理画面を圧倒的な速さで、かつビジネスのスケールに合わせて柔軟に構築することができるローコードツールです。

管理画面の構築もWeb上で完結
エンジニアのためのローコードツール

Querierについて詳しく見る

本記事ではGo言語を使用してFirestoreのデータ操作を行う方法について解説します。

FirestoreはGoogleのNoSQLベースであり、データの取得、追加、更新、削除などの操作が可能です。

特に、Firestoreのデータ取得に焦点を当て、単一ドキュメントの取得方法、複数ドキュメントの取得方法、条件を指定してデータを取得する方法、およびページングの実装方法について説明します。

データの取得

単一ドキュメントの取得

Firestoreから単一のドキュメントを取得するには、DocumentSnapshotを使用します。

以下は、指定されたコレクションとドキュメントIDに基づいて単一のドキュメントを取得する関数のサンプルコードです。

func getDocument(collection string, docID string) (*firestore.DocumentSnapshot, error) {
    ctx := context.Background()
    client, err := firestore.NewClient(ctx, "projectID")
    if err != nil {
        return nil, err
    }

    defer client.Close()
    docRef := client.Collection(collection).Doc(docID)
    snapshot, err := docRef.Get(ctx)
    if err != nil {
        return nil, err
    }

    return snapshot, nil
}

使用例:

snapshot, err := getDocument("users", "userID")
if err != nil {
    log.Fatal(err)
}


data := snapshot.Data()
// データの利用

複数ドキュメントの取得

Firestoreから複数のドキュメントを取得するには、Queryを使用します。

以下は、指定されたコレクションとフィールドに基づいて複数のドキュメントを取得する関数のサンプルコードです。

func getDocuments(collection string, field string) ([]*firestore.DocumentSnapshot, error) {
    ctx := context.Background()
    client, err := firestore.NewClient(ctx, "projectID")
    if err != nil {
        return nil, err
    }

    defer client.Close()
    query := client.Collection(collection).Where(field, "==", "value")
    snapshots, err := query.Documents(ctx).GetAll()
    if err != nil {
        return nil, err
    }
    return snapshots, nil
}

使用例:

snapshots, err := getDocuments("users", "age")
if err != nil {
    log.Fatal(err)
}

for _, snapshot := range snapshots {
    data := snapshot.Data()
    // データの利用
}

条件を指定して取得

Firestoreから条件を指定してデータを取得するには、Whereメソッドを使用します。

以下は、指定されたコレクション、フィールド、演算子、値に基づいてデータを取得する関数のサンプルコードです。

func getDocumentsWithCondition(collection string, field string, operator string, value interface{}) ([]*firestore.DocumentSnapshot, error) {
    ctx := context.Background()
    client, err := firestore.NewClient(ctx, "projectID")
    if err != nil {
        return nil, err
    }

    defer client.Close()
    query := client.Collection(collection).Where(field, operator, value)
    snapshots, err := query.Documents(ctx).GetAll()
    if err != nil {
        return nil, err
    }

    return snapshots, nil
}

使用例:

snapshots, err := getDocumentsWithCondition("users", "city", "==", "Tokyo")
if err != nil {
    log.Fatal(err)
}

for _, snapshot := range snapshots {
    data := snapshot.Data()
    // データの利用
}

ページングを実装する

Firestoreで大量のデータを取得する場合は、ページネーションを実装することが効果的です。

以下は、指定されたコレクション、フィールド、ページサイズ、開始位置に基づいてページングを行う関数のサンプルコードです。

func getPagedDocuments(collection string, field string, pageSize int, startAfter *firestore.DocumentSnapshot) ([]*firestore.DocumentSnapshot, error) {
    ctx := context.Background()
    client, err := firestore.NewClient(ctx, "projectID")
    if err != nil {
        return nil, err
    }

    defer client.Close()
    query := client.Collection(collection).OrderBy(field).Limit(pageSize)
    if startAfter != nil {
        query = query.StartAfter(startAfter)
    }
    snapshots, err := query.Documents(ctx).GetAll()
    if err != nil {
        return nil, err
    }

    return snapshots, nil
}

使用例:

pageSize := 10
var startAfter *firestore.DocumentSnapshot

snapshots, err := getPagedDocuments("users", "name", pageSize, startAfter)
if err != nil {
    log.Fatal(err)
}

for _, snapshot := range snapshots {
    data := snapshot.Data()
    // データの利用
}

データの追加

IDを指定しないで構造体を追加

Firestoreに新しいドキュメントを追加するには、Collectionに対してAddメソッドを使用します。

以下は、指定されたコレクションとデータに基づいて新しいドキュメントを追加する関数のサンプルコードです。

func addDocument(collection string, data interface{}) error {
    ctx := context.Background()
    client, err := firestore.NewClient(ctx, "projectID")
    if err != nil {
        return err
    }

    defer client.Close()
    _, _, err = client.Collection(collection).Add(ctx, data)
    if err != nil {
        return err
    }

    return nil
}

使用例:

type User struct {
	Name string `firestore:"name,omitempty"`
	Age  int    `firestore:"age,omitempty"`
	City string `firestore:"city,omitempty"`
}

user := User{Name: "John", Age: 30, City: "Tokyo"}

err := addDocument("users", user)
if err != nil {
    log.Fatal(err)
}

IDを指定しないでmapを追加

Firestoreに新しいドキュメントを追加するには、Collectionに対してAddメソッドを使用します。

以下は、指定されたコレクションとデータ(map)に基づいて新しいドキュメントを追加する関数のサンプルコードです。

func addMapDocument(collection string, data map[string]interface{}) error {
  ctx := context.Background()
  client, err := firestore.NewClient(ctx, "projectID")
  if err != nil {
    return err
  }

  defer client.Close()
  _, _, err = client.Collection(collection).Add(ctx, data)
  if err != nil {
    return err
  }

  return nil
}

使用例:

data := map[string]interface{}{
    "name": "John",
    "age": 30,
    "city": "Tokyo",
}

err := addMapDocument("users", data)
if err != nil {
    log.Fatal(err)
}

IDを指定して構造体を追加

Firestoreに新しいドキュメントを追加するには、Collectionに対してDocメソッドを使用してドキュメントの参照を取得し、Setメソッドでデータを追加します。

以下は、指定されたコレクション、ドキュメントID、およびデータに基づいて新しいドキュメントを追加する関数のサンプルコードです。

func setDocument(collection string, docID string, data interface{}) error {
    ctx := context.Background()
    client, err := firestore.NewClient(ctx, "projectID")
    if err != nil {
        return err
    }

    defer client.Close()
    _, err = client.Collection(collection).Doc(docID).Set(ctx, data)
    if err != nil {
        return err
    }

    return nil
}

使用例:

type User struct {
	Name string `firestore:"name,omitempty"`
	Age  int    `firestore:"age,omitempty"`
	City string `firestore:"city,omitempty"`
}

user := User{Name: "John", Age: 30, City: "Tokyo"}

err := setDocument("users", "userID", user)
if err != nil {
    log.Fatal(err)
}

IDを指定してmapを追加

Firestoreに新しいドキュメントを追加するには、Collectionに対してDocメソッドを使用してドキュメントの参照を取得し、Setメソッドでデータを追加します。

以下は、指定されたコレクション、ドキュメントID、およびデータ(map)に基づいて新しいドキュメントを追加する関数のサンプルコードです。

func setMapDocument(collection string, docID string, data map[string]interface{}) error {
    ctx := context.Background()
    client, err := firestore.NewClient(ctx, "projectID")
    if err != nil {
        return err
    }

    defer client.Close()
    _, err = client.Collection(collection).Doc(docID).Set(ctx, data)
    if err != nil {
        return err
    }

    return nil
}

使用例:

data := map[string]interface{}{
    "name": "John",
    "age": 30,
    "city": "Tokyo",
}

err := setMapDocument("users", "userID", data)
if err != nil {
    log.Fatal(err)
}

3. データの更新

構造体のデータを更新

Firestoreのドキュメントのデータを更新するには、SetメソッドまたはUpdateメソッドを使用します。

以下は、指定されたコレクション、ドキュメントID、および更新データ(構造体)に基づいてデータを更新する関数のサンプルコードです。

func updateDocument(collection string, docID string, data interface{}) error {
    ctx := context.Background()
    client, err := firestore.NewClient(ctx, "projectID")
    if err != nil {
        return err
    }

    defer client.Close()
    _, err = client.Collection(collection).Doc(docID).Set(ctx, data, firestore.MergeAll)
    if err != nil {
        return err
    }

    return nil
}

使用例:

type User struct {
	Name string `firestore:"name,omitempty"`
	Age  int    `firestore:"age,omitempty"`
	City string `firestore:"city,omitempty"`
}

user := User{Name: "John", Age: 35, City: "Osaka"}

err := updateDocument("users", "userID", user)
if err != nil {
    log.Fatal(err)
}

mapのデータを更新

Firestoreのドキュメントのデータを更新するには、SetメソッドまたはUpdateメソッドを使用します。

以下は、指定されたコレクション、ドキュメントID、および更新データ(map)に基づいてデータを更新する関数のサンプルコードです。

func updateMapDocument(collection string, docID string, data map[string]interface{}) error {
    ctx := context.Background()
    client, err := firestore.NewClient(ctx, "projectID")
    if err != nil {
        return err
    }

    defer client.Close()
    _, err = client.Collection(collection).Doc(docID).Set(ctx, data, firestore.MergeAll)
    if err != nil {
        return err
    }

    return nil
}

使用例:

data := map[string]interface{}{
    "age": 35,
    "city": "Osaka",
}

err := updateMapDocument("users", "userID", data)
if err != nil {
    log.Fatal(err)
}

データの削除

ドキュメントの削除

Firestoreからドキュメントを削除するには、Deleteメソッドを使用します。以下は、指定されたコレクションとドキュメントIDに基づいてドキュメントを削除する関数のサンプルコードです。

func deleteDocument(collection string, docID string) error {
    ctx := context.Background()
    client, err := firestore.NewClient(ctx, "projectID")
    if err != nil {
        return err
    }

    defer client.Close()
    _, err = client.Collection(collection).Doc(docID).Delete(ctx)
    if err != nil {
        return err
    }

    return nil
}

使用例:

err := deleteDocument("users", "userID")
if err != nil {
    log.Fatal(err)
}

データ内の一部データを削除

Firestoreのドキュメント内の一部のデータを削除するには、Updateメソッドを使用します。以下は、指定されたコレクション、ドキュメントID、および削除するフィールドパスに基づいてデータを削除する関数のサンプルコードです。

func deleteField(collection string, docID string, fieldPath string) error {
    ctx := context.Background()
    client, err := firestore.NewClient(ctx, "projectID")
    if err != nil {
        return err
    }

    defer client.Close()
    _, err = client.Collection(collection).Doc(docID).Update(ctx, []firestore.Update{
        {Path: fieldPath, Value: firestore.Delete},
    })
    if err != nil {
        return err
    }

    return nil
}

使用例:

err := deleteField("users", "userID", "city")
if err != nil {
    log.Fatal(err)
}

コレクションの削除

Firestoreのコレクション内の全てのドキュメントを削除するには、バッチ処理を使用します。以下は、指定されたコレクションに含まれる全てのドキュメントを削除する関数のサンプルコードです。

func deleteCollection(collection string) error {
    ctx := context.Background()
    client, err := firestore.NewClient(ctx, "projectID")
    if err != nil {
        return err
    }

    defer client.Close()
    batch := client.Batch()
    docs, err := client.Collection(collection).Documents(ctx).GetAll()
    if err != nil {
        return err
    }

    for _, doc := range docs {
        batch.Delete(doc.Ref)
    }

    _, err = batch.Commit(ctx)
    if err != nil {
        return err
    }

    return nil
}

使用例:

err := deleteCollection("users")
if err != nil {
    log.Fatal(err)
}

さいごに

本記事では、Go言語を使用してFirestoreのデータ操作を行う方法について解説しました。

単一ドキュメントの取得方法、複数ドキュメントの取得方法、条件を指定してデータを取得する方法、およびページングの実装方法について詳細に説明しました。

また、データの追加、更新、削除に関するメソッドも示しました。

これらの方法を活用して、効率的なFirestoreデータ操作を実現してください。

【参考リンク】


「Querier(クエリア)」は社内向け管理画面を圧倒的な速さで、かつビジネスのスケールに合わせて柔軟に構築することができるローコードツールです。

最新の記事

【告知】値の参照時の仕様変更のお知らせ

このたび2024年11月11日に値の参照に関する仕様変更を予定しておりますので詳細について報告いたします。

more

管理画面の構築もWeb上で完結
エンジニアのためのローコードツール

Querierについて詳しく見る