14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

FirestoreにINQueryが対応されたのでSDK,Ballcapで試してみる

Last updated at Posted at 2019-11-08

この記事について

FirestoreでついにIN句がサポートされましたね:v:

Firestoreでは投げれないQueryをAlgoliaにお任せするようなケースはありそうですが、
今回の更新によってOR検索についてはAlgoliaに頼らずともFirestoreで完結してできそうですね!(制限の内容にもよりますが:sweat_smile:)

そこで今回はSDK,FirestoreのラッパーライブラリであるBallcapそれぞれで試してみた内容とIN句の制限について書いてみました:hugging:

前提

FirestoreにMoviesCollectionを用意し、
複数のDocumentがMoviesCollectionに入ってる状態を作ってます。

全体的なPathイメージはこちら
/movies/{movieId}

スクリーンショット 2019-11-08 16.44.33.png

各Documentのデータ内容
スクリーンショット 2019-11-08 16.43.35.png

Ballcap使用の場合についても今回の記事で触れるためModelについて

import Ballcap

struct Movies: Codable, Equatable, Modelable {
    var name: String = ""
    var category: [String] = []
    var tag: String = ""
}

IN Query

tagFieldにnewもしくはrecommendが存在しているDocumentを取得

SDK

db.collection("movies")
    .whereField("tag", in: ["new", "recommend"])
    .addSnapshotListener { (querySnapshot, error) in
        if let error = error {
            print(error)
        }
        if let documents = querySnapshot?.documents {
            for doc in documents {
                print("data:\(doc.data())")
            }
        }
}

Ballcap

Document<Movies>
    .where("tag", in: ["new", "recommend"])
    .dataSource().onCompleted { (_, movies) in
        for movie  in movies {
            print("movie:\(movie.data?.name)")
        }
}.get()

ArrayContainAny Query

categoryFieldにhorrorもしくはthrillerが存在しているDocumentを取得
SDK

db.collection("movies")
    .whereField("category", arrayContainsAny: ["horror", "thriller"])
    .addSnapshotListener { (querySnapshot, error) in
        if let error = error {
            print(error)
        }
        if let documents = querySnapshot?.documents {
            for doc in documents {
                print("doc:\(doc.data())")
            }
        }
}

Ballcap

Document<Movies>
    .where("category", arrayContainsAny: ["horror", "thriller"])
    .dataSource().onCompleted { (_, movies) in
        for movie in movies {
            print("movie:\(movie.data?.name)")
        }
}.get()

制限について

IN Queryに対する制限は以下二つになります。
現在、クエリでは最大10個の異なる値に制限されています。

// 10件まで!
whereField("number", in: ["1","2","3","4","5","6","7","8","9","10"])

単一のクエリでは、これらのタイプの操作のうち1つのみを使用できます


// 新しくFiledを設けてうまく使えば制限超えれるのでは?もダメ
whereField("number", in: ["1","2","3","4","5","6","7","8","9","10"])
whereField("number2", in: ["11","12","13","14","15","16","17","18","19","20"])

ちなみに10件超える場合はクラッシュします:angel_tone5:

reason: 'Invalid Query. 'arrayContainsAny' filters support a maximum of 10 elements in the value array.'
reason: 'Invalid Query. 'in' filters support a maximum of 10 elements in the value array.'

参考

Cloud FirestoreでINクエリがサポートされるようになりました!

Querying and filtering data

Firestore
↑ここの更新ちらほらみてるとリリース発表前に気付けたりします

使用したライブラリ

Ballcap-iOS

余談

お世話になってるライブラリに今回のIN句対応がmergeされました:v:
まだまだ中身追いきれてないですがQueryあたりは直近でみてたのでタイミングがよかったです!
スクリーンショット 2019-11-08 17.41.28.png

14
8
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
14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?