LoginSignup
2
1

More than 1 year has passed since last update.

超基礎:Python Firebase Admin SDKによる位置情報データの取り扱い データの登録編

Last updated at Posted at 2021-11-30

Location Tech Advent Calendar 2021 by LBMA Japan 🛰 Advent Calendar 2021の1日目ということで、Firestoreのデータベースに位置情報データを投入するというごく基本的な記事を書いていきます!

対象

Firebase Firestoreを使い始めた人
位置情報データを扱いたい人

背景

Firebase Firestoreは、JSONのようなスキーマでデータを出し入れできるGoolge Cloud Platformのデータベースで、極めて高速・柔軟にデータの処理ができます。

一方で、制約条件も多くあります。例えば、Firestoreに登録されたデータを2つ以上のフィールドを用いて検索することは基本的にはできません。SQLでいうと、「Where句で2つ以上のフィールドを使った条件分が書けない」というようなイメージです。このようなリレーショナル・データベースだとあまり考えられないような制約条件が、Firebaseには他にもいくつかあります。

こうした制約条件は一見厳しいように見えますが、通常の場合、クライアント側で解決が可能です。例えば、「1つのフィールドしか検索できない」という制約条件については、「1つのフィールドで検索して、結果をクライアント側に持ってきて、クライアント側でより細かく絞る」ということが可能なので、大きな問題にはなりません。

しかし、位置情報データを取り扱う場合には、大きな問題が生じます。というのは、緯度と経度で定義される「位置情報」は、「緯度だけ」や「経度だけ」のように、片方だけで利用するケースがほぼ無いからです。仮に緯度だけで絞ったとしても、ものすごくたくさんのデータがヒットしてしまい、たいてい、クライアントでの処理が大変遅くなってしまいます。つまり、Firebaseで緯度と経度を

スクリーンショット 2021-11-30 12.50.18.png

というように登録してしまうと、パフォーマンス上色々問題が出てしまいます。

そこで、FirestoreではGeoPoint型と呼ばれる型を導入することで、この問題に対処しています。これは、緯度と経度が一緒になったフィールドです。 緯度と経度を同時に持つので、GeoPoint型で検索すれば、Firestoreの「1つのフィールドでしか検索できない」制限をクリアすることができるように思えます。

しかし、ここでも1つ問題があります。それは、FirestoreではGeoPoint型を直接指定してクエリを打つことができないという問題です。例えば、「このGeoPoint型のデータの半径50m以内のドキュメントをもってきてください」というようなことが、現状のFirestoreではできません。そのため、ちょっとした工夫が必要になります。

こうした点を背景に、以下では、Python Firebase Admin SDKを用いた位置情報データの登録方法について解説していきます。検索方法については次の記事にて。

位置情報データの登録

バージョン情報

本記事では以下のバージョンで実施しています。

[tool.poetry.dependencies]
python = "^3.9"
firebase-admin = "^5.0.3"
google-cloud = "^0.34.0"

型やクライアントの準備

主として利用するのはFirebase Admin SDKですが、型ヒント(type-hint)を使うために、google-cloud側のfirestoreライブラリも利用します。

from firebase_admin import initialize_app, firestore
from google.cloud.firestore import AsyncDocumentReference, AsyncCollectionReference, GeoPoint

initialize_app(options={"projectId":"Your_GCP_PROJECT_ID"})
db_client = firestore.AsyncClient()

コレクションの定義

コレクションへのリファレンスを定義します。ここではlocationsというリファレンスを作ります。

locations_ref: AsyncCollectionReference = db_client.collection('locations')

これで準備は終了です。

位置情報データの追加

最後の位置情報データを追加する処理について書きます。locationsコレクションにgeopointというフィールドを持つドキュメントを追加していきます。

# GeoPoint型のデータをもつdataを定義
data = {"geopoint": GeoPoint(38.1233, 139.7548968)}
# 追加
result_doc_ref: AsyncDocumentReference
_,result_doc_ref =  await locations_ref.add(data)

print(result_doc_ref.to_dict()['geopoint'].latitude)
# >> 35.7018944

格納した結果(値は異なっていますが)

スクリーンショット 2021-11-30 12.58.29.png

上記の手順により、Firestoreに追加することはできました。しかし、背景で説明したとおり、FirebaseにはGeoPointで検索をする機能がありません。そこで、実用的に使うためには、もうひと工夫が必要です。こうした検索の工夫については、次の記事で書きますね。

参考

firestore client 公式ドキュメント
https://googleapis.dev/python/firestore/latest/client.html

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1