Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Firestore のクエリと全文検索
Search
miup
August 07, 2018
Programming
3.6k
7
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Firestore のクエリと全文検索
Firebase Meetup #5
miup
August 07, 2018
More Decks by miup
See All by miup
Algolia with Firebase
miup
2
1.5k
Firestore, Cloud Storage を用いた アプリ内での画像の扱い方
miup
5
25k
Firebase Cloud Messaging 入門編
miup
0
5.2k
The way of truly serverless application
miup
1
4.6k
Other Decks in Programming
See All in Programming
Performance Engineering for Everyone
elenatanasoiu
0
270
【SRE NEXT 2026 Lunch Session】一人目専任SREの立ち上げを加速する ― AIと進めたオンボーディングで2分を0.04秒にした話
pkshadeck
PRO
0
2.3k
AI 輔助遺留系統現代化的經驗分享
jame2408
1
1.2k
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
4
1.1k
AIエージェントで 変わるAndroid開発環境
takahirom
2
510
【やさしく解説 設計編・中級 #6】良いアーキテクチャとは ~ 一本の登り道の、行き先 ~
panda728
PRO
0
150
コーディングルールの鮮度を保ちたい for SRE NEXT 2026 / keep-fresh-go-internal-conventions-sre-next-2026
handlename
0
140
Vite+ Unified Toolchain for the Web
naokihaba
0
740
SREの積み重ねがAI駆動開発のガードレールになった ― 7つの実践/SRE Guardrails The 7
tomoyakitaura
8
4k
ビデオ通話が繋がる0.2秒で何が起きているのか
supurazako
2
130
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
170
Embedded SREと共に達成した会員管理システムのAWS移行 - SRE NEXT 2026 ランチスポンサーセッション
niftycorp
PRO
1
2.3k
Featured
See All Featured
Between Models and Reality
mayunak
4
370
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
320
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
750
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
220
HDC tutorial
michielstock
2
740
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.8k
Thoughts on Productivity
jonyablonski
76
5.2k
Practical Orchestrator
shlominoach
191
11k
Bootstrapping a Software Product
garrettdimon
PRO
307
120k
Into the Great Unknown - MozCon
thekraken
41
2.6k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.2k
Transcript
Cookpad Inc. Firestore ͷΫΤϦͱશจݕࡧ ࡾӜ
Cookpad Inc. All Rights Reserved. ࣗݾհ w໊લࡾӜ wܦྺ wCookpad 17৽ଔ
(Komerco ࣄۀ෦ wiOSྺ5 Firebase ྺ1ͪΐͬͱ wTwitter: __miup (ΞϯμʔείΞ2ຊʂ wGithub: miuP
Cookpad Inc. All Rights Reserved. ࠓ͢͜ͱ wFirestore ͷΫΤϦͰͰ͖Δ͜ͱ wFirestore ͷΫΤϦͰͰ͖ͳ͍͜ͱ
wղܾࡦ
Cookpad Inc. All Rights Reserved. Firestore ͷΫΤϦͰͰ͖Δ͜ͱ wsort worderBy wwhere
wisEqualTo wisLessThan (orEqualTo) wisGreaterThan (orEqualTo)
Cookpad Inc. All Rights Reserved. Firestore ͷΫΤϦͰͰ͖Δ͜ͱ wpaging wlimit wstartAfter,
endBefore (order ͍ͯ͠Δ, DocumentReference) wetc…
Cookpad Inc. All Rights Reserved. Firestore ͷΫΤϦͰͰ͖Δ͜ͱ 1ճͷΫΤϦͰ isLessThan ͱ
isGreaterThan 1ͭͷ Field ʹର͔ͯ͑͠͠ͳ͍ʂ ͨͩ͠ʂ ੍͕͋Δ
interface Product { name: string // ໊ price: number //
Ձ֨ stock: number // ࡏݿ isActive: boolean // ཧআ createdAt: firestore.Timestamp updatedAt: firestore.Timestamp }
Cookpad Inc. All Rights Reserved. Firestore ͷΫΤϦͰͰ͖Δ͜ͱ w୯ҰͷϑΟʔϧυʹର͢Δෳͷൣғൺֱ wෳͷϑΟʔϧυʹର͢ΔՁԋࢉࢠ wެ։தͷ5000ԁ~10000ԁͷࡏݿͷlͳ͍zΛऔಘ
const products = await admin.firestore().collection('products') .where('isActive', '==', true) .where(‘stock', '==',
0) .where('price', '<=', 10000) .where('price', ‘>=', 5000) .then(querySnapshot => { return querySnapshot.docs.map(doc => { ... }) })
Cookpad Inc. All Rights Reserved. Firestore ͷΫΤϦͰͰ͖Δ͜ͱ wෳͷϑΟʔϧυʹ·͕ͨΔΫΤϦ wΧελϜΠϯσοΫε͕ඞཁ ෳ߹ΠϯσοΫεΈ͍ͨͳͷʣ
wΫΤϦ͛ͯΤϥʔ͕ฦͬͯ͘Δͱ URL ͕ॻ͍ͯ͋ΔͷͰͦ͜ Λ౿Ί؆୯ʹઃఆͰ͖Δ
Cookpad Inc. All Rights Reserved. Firestore ͷΫΤϦͰͰ͖ͳ͍͜ͱ wશจݕࡧ -*,&
wisNotEqualTo (݁ߏͭΒ͍) wෳͷϑΟʔϧυʹର͢Δൣғൺֱ wެ։தͷ5000ԁ~10000ԁͷࡏݿͷl͋ΔzΛऔಘ
const products = await admin.firestore().collection('products') .where('isActive', '==', true) .where('stock', '>',
0) .where('price', '<=', 10000) .where('price', ‘>=', 5000) .then(querySnapshot => { return querySnapshot.docs.map(doc => { ... }) }) ❌
const products = await admin.firestore().collection('products') .where('isActive', '==', true) .where('stock', '!=',
0) .where('price', '<=', 10000) .where('price', ‘>=', 5000) .then(querySnapshot => { return querySnapshot.docs.map(doc => { ... }) }) ❌
Cookpad Inc. All Rights Reserved. Firestore ͷΫΤϦͰͰ͖ͳ͍͜ͱ wެ։தͷ5000ԁ~10000ԁͷࡏݿͷl͋ΔzΛऔಘ͕Ͱ͖ͳ͍ wશจݕࡧ͕Ͱ͖ͳ͍ ݁ߏݫ͍͠
Cookpad Inc. All Rights Reserved. Ͳ͏͢Εʜ
Cookpad Inc. All Rights Reserved. Algolia 4BB4ʹཔΖ͏ શจݕࡧʢincremental search) Λఏڙ͍ͯ͠Δ
SaaS iOS, Android, Web Ͱ SDK ఏڙ͞Ε͍ͯΔ ʢଞʹݕࡧ4BB4͋Δ͚Ͳެࣜʹ໊લ͕ग़͍ͯΔͷͰ"MHPMJBΛհ͠·͢ʣ
Cookpad Inc. All Rights Reserved. ྲྀΕ Cloud Firestore Cloud Functions
Algolia Save Document Event trigger Algolia API Search
algoliasearch(functions.config().algolia.app_id, functions.config().algolia.api_key) const productsIndex = algolia.default.initIndex('products') functions.firestore.document('products/{productID}').onCreate(async (snapshot, context) =>
{ const firProduct = new Tart.Snapshot<Firebase.Product>(snapshot) // আࡁΈͷొ͠ͳ͍ if (!firProduct.data.isActive) { return undefined } // Algolia ʹอଘ͢Δσʔλʹม(Reference Λ ID ʹ͢Δͱ͔͢Δ) const product = new Product(firProduct) return new Promise((resolve, reject) => { productsIndex.addObject(product, async (error, response) => { if (error) { throw error } else { resolve(response) } }) }) })
Cookpad Inc. All Rights Reserved. ྲྀΕ Cloud Firestore Cloud Functions
Algolia Save Document Event trigger Algolia API Search
Cookpad Inc. All Rights Reserved. ܕ͕ͳ͍ Algolia ݕࡧ݁Ռʹܕ͕ͳ͍ Swift Ͱॻ͘ͳΒܕ͕ཉ͍͠
Kotlin Ͱ Java Ͱ TypeScript Ͱಉ͚ͩ͡Ͳ
Cookpad Inc. All Rights Reserved. ϥΠϒϥϦ࡞ͬͨ
Cookpad Inc. All Rights Reserved. Algent Type Safe Algolia Search
Client for Swift https://github.com/miuP/Algent
Cookpad Inc. All Rights Reserved. ͍ํ wσʔλͷܕΛ࡞Δ wRequest Λ࡞Δ w͛Δ
struct User: Decodable { let objectID: String let name: String
let bio: String let isActive: Bool let followerCount: Int let followeeCount: Int let _tags: [String] }
struct SarchUserRequest: AlgoliaRequestProtocol { // set search result type typealias
HitType = User let page: Int let per: Int let text: String? let hashtags: [String]? var indexName: String { return "user" } var query: AlgentQuery { let query = AlgentQuery(query: text) query.page = UInt(page) query.hitsPerPage = UInt(per) if let hashtags = hashtags { query.tagFilters = hashtags } return query } init(page: Int, per: Int, text: String? = nil, hashtags: [String]? = nil) { self.page = page self.per = per self.text = text self.hashtags = hashtags } }
let request = SarchUserRequest(page: 0, per: 20, text: "", hashtags:
[]) Algent.shared.search(request: request) { result in switch result { case .success(let response): // response is AlgoliaResponse<Request.HitType> print(response.hits) // see hit object:[HitType] case .failure( let error): print(error) } }
Cookpad Inc. All Rights Reserved. ·ͱΊ wFirestore ͰͷΫΤϦ wൣғࢦఆΛҟͳΔFieldʹ͔͚ΒΕͳ͍ wisNotEqualTo
͕ͳ͍ wLIKEͱ͔શจݕࡧ͕Ͱ͖ͳ͍ wAlgolia w֎෦αʔϏεʹͳΔͷͰ࿈ܞ͕ඞཁ(Firebase ͷ༗ྉϓϥϯඞཁ) wAlgent ͬͯΈ͍ͯͩ͘͞