狠狠撸

狠狠撸Share a Scribd company logo
Firestoreでマスタ取得を
効率化するいくつかの方法
西宮大貴( @hnishim)
今日のお題:以下についてFJUGの
皆さまにいただいた提案をまとめた
● 数百?1,000件のマスタデータ用ドキュメントが
Firestore上にあり、ユーザ(iOS)は日々の操作でそ
のマスタから選択したいデータを選ぶようにしたい
● 部分一致検索をさせたいので、Firestoreからデータ取
得するときのwhere句で都度取得はNG
● 選択時に使用する情報はマスタデータの全情報ではな
く、名前(など)だけでOK
案1
● 本物のマスタデータ(gins)とは
別に専用のコレクション(
masterSummary)を作り、そ
の中に1ドキュメントだけ保持
● masterSummaryのドキュメン
トに配列 or マップ(辞書)型
でマスタデータの名前を格納
● マスタデータの変更時に
FunctionsでmasterSummaryド
キュメントへ変更を反映
案2
● 案1と同様だが、マスタデータ
の変更時に、マスタサマリも
更新する処理を組み込む
案3
● そもそもクライアントにマス
タデータをダウンロードせず
にFirestore上で部分一致検索
実現してしまう
○ 基本的に n-gram
○ マスタドキュメントに名前を前方
から1文字づつ削った値を全パタ
ーン保持
○ それぞれの配列に前方一致検索を
かける
以下記事参照 前方一致検索:https://note.mu/shogoyamada/n/n8fe9486fcbec
n-gram 的な部分一致検索:
https://qiita.com/oukayuka/items/d3cee72501a55e8be44a
案4
● マスタデータ(gins)とは別にマ
スタのバージョン情報を持た
せ、マスタデータが更新され
るたびにバージョンを
increment
● クライアント側でバージョン
情報を比較して差異があれば
マスタデータを取得
ということで案4で実装しました
if let v = UserDefaults.standard.dictionary(forKey: "masterVersion") {
versionOnClient = v["gins"] as? Int ?? 0
}
db.collection("settings").document("masterVersions").getDocument() { (document, error) in
versionOnFS = document.data()[“gins”] as? Int ?? 0
let source: FirestoreSource = (versionOnClient == versionOnFS) ? .cache : .default
var docs = [DocumentSnapshot]()
self.db.collection(“gins”).getDocuments(source: source) { (querySnapShot, err) in
docs = querySnapShot!.documents
versionOnClient = versionOnFS
UserDefaults.standard.set(versionOnClient, forKey: "masterVersion")
masterData = docs.compactMap({ Master(key: $0.documentID, data: $0.data()!) })
}
}
ということで案4で実装しました
import * as admin from 'firebase-admin';
import { FieldValue } from '@google-cloud/firestore';
admin.initializeApp(functions.config().firebase);
const firestore = admin.firestore();
export const onWriteMasterGins = functions.firestore.document('/gins/{recordId}',)
.onWrite(async (change, context) => {
await incrementGinsVersion(change, context);
});
async function incrementGinsVersion(_snapshot:
functions.Change<FirebaseFirestore.DocumentSnapshot> | undefined, context:
functions.EventContext) {
await firestore.collection('systemData').doc('masterVersions')
.set({gins: FieldValue.increment(1.0)}, {merge: true});
}
Thank you!
@GinbaseApp
Ginbase
お酒「ジン」専用の記録アプリを個人開発してます。

More Related Content

贵颈谤别蝉迟辞谤别でマスタ取得を?効率化するいくつかの方法