JavaScript
Firebase
Firestore

firestore で配列の検索・追加・削除がサポートされたので試してみた

firebase JavaScript SDK v5.3.0 がリリースされた(July 19, 2018)。そしてこのバージョンでめでたく firestore で配列の検索 array-contains 、要素の追加 arrayUnion と要素の削除 arrayRemove がサポートされた。本当にめでたい。firestore を使っていない人からしたら配列の検索・追加・削除がそんなに嬉しいのか?と思うかも知れないが、本当に嬉しいのです。

例えば、firestore はドキュメント指向なので以下のようなデータを持つことができる。

{
  "name": "zaru",
  "items_array": [
    "foo",
    "bar"
  ]
}

MongoDB のように柔軟に良い感じに使えそう。

配列の検索

では、この itemsfoo を持っているデータを検索しようとするとどうなるかというと、普通にはできなかった。今までは。検索クエリが単純な <, <=, ==, >=, > しかなかったため、 items の n 番目に存在しているかも知れないというクエリは書けなかった。

なので、代替案として以下のパターンが推奨されていた。

{
  "name": "zaru",
  "items_object": {
    "foo": true
    "bar": true
  }
}

そう、配列の代わりにオブジェクト(ハッシュ)を使ってくれということ。これなら以下のようなクエリが書ける。

DB.collection('sample').where('items_object.foo', '==', true).get().then(res => {
  res.forEach(doc => {
  })
})

これが v5.3.0 からは配列であっても array-contains を使えば検索できる。

DB.collection('sample').where('items_array', 'array-contains', 'foo').get().then(res => {
  res.forEach(doc => {
  })
})

素晴らしい。配列データをちゃんと配列として使うことができて嬉しい。なお、検索パフォーマンスは、1000件程度の場合では配列でもオブジェクトでも違いが見られなかった。インデックスがちゃんと効いているっぽい気がする。

要素の追加

配列に要素を追加するのも今まではできなかった。まるごと update するしかなかった。

DB.collection('sample').doc('doc').update({
  items_array: firebase.firestore.FieldValue.arrayUnion('zaru', 'soba')
})

要素の削除

配列の削除はこちら。

DB.collection('sample').doc('doc').update({
  items_array: firebase.firestore.FieldValue.arrayRemove('zaru', 'soba')
})

これで firestore でも配列をふんだんに使ったデータ構造ができますね。嬉しい。