Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Firestore のクエリと全文検索
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
【高い買い物LT会】初任給で話題の国産フィジカルAIを買った話
akagami
PRO
0
140
XHTMLが残したもの
yosuke_furukawa
PRO
2
690
tsc.rip を支える技術 / Kyoto.なんか #8
susisu
0
4.4k
MIZARU@SPAJAM2026 第二回予選
1901drama
0
110
Building an Out-of-Order CPU
latte72
1
750
AWS Step Functions 大規模並列の壁を越える / jaws-sonic-2026-niigata-step-functions
kasacchiful
PRO
1
440
世界の中心で、AI(App Intents)をさけぶ ー App Intents中心設計の実践ガイド
touyou
0
390
iOS開発×AI駆動開発 〜最近使って便利だったスキルの話〜
nogu66
0
140
Streamlitで実現する自然言語データアプリ開発
ayumu_yamaguchi
0
110
Deep dive into the select statement (GopherCon UK)
jespino
0
170
LLMは4年分のCompose移行を再現できるのか?実プロダクト279件のXMLで探る自動化の境界線
makun
0
540
Family mrubyの進捗
kishima
1
110
Featured
See All Featured
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.6k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.6k
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
[RailsConf 2023] Rails as a piece of cake
palkan
59
7k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
780
Rails Girls Zürich Keynote
gr2m
96
14k
Designing for humans not robots
tammielis
254
26k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
1.2k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.9k
Design in an AI World
tapps
1
310
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
280
Bash Introduction
62gerente
615
220k
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 ͬͯΈ͍ͯͩ͘͞