web-dev-qa-db-ja.com

Google Firestore:プロパティ値の部分文字列のクエリ(テキスト検索)

シンプルな検索フィールドを追加したいのですが、次のようなものを使用したいと思います

collectionRef.where('name', 'contains', 'searchTerm')

where('name', '==', '%searchTerm%')を使用しようとしましたが、何も返されませんでした。

60
tehfailsafe

そのような演算子はありません。許可される演算子は==<<=>>=です。

たとえば、barfooの間で始まるすべてのものに対して、プレフィックスのみでフィルタリングできます。

collectionRef.where('name', '>=', 'bar').where('name', '<=', 'foo')

Algolia またはElasticSearchのような外部サービスを使用できます。

17
Kuba

Kubaの答えは制限事項に関する限り真実ですが、セットのような構造でこれを部​​分的にエミュレートできます。

{
  'terms': {
    'reebok': true,
    'mens': true,
    'tennis': true,
    'racket': true
  }
}

これで、クエリを実行できます

collectionRef.where('terms.tennis', '==', true)

Firestoreはすべてのフィールドのインデックスを自動的に作成するため、これは機能します。残念ながら、Firestoreは複合インデックスを自動的に作成しないため、これは複合クエリに対して直接機能しません。

単語の組み合わせを保存することでこれを回避できますが、これはfastい高速になります。

おそらく、アウトボード 全文検索 を使用する方が良いでしょう。

30
Gil Gilbert

Firebaseは、文字列内の用語の検索を明示的にサポートしていません...

ただし、Firebaseは現在、以下をサポートしています。これは、あなたや他の多くの問題を解決します

2018年8月の時点で、array-containsクエリをサポートしています。参照: https://firebase.googleblog.com/2018/08/better-arrays-in-cloud-firestore.html

すべてのキー用語をフィールドとして配列に設定し、「X」を含む配列を持つすべてのドキュメントを照会できるようになりました。論理ANDを使用して、additionalクエリのさらなる比較を行うことができます。(これは、firebase が複数の配列を含む複合クエリを現在ネイティブにサポートしていないためです。クエリ したがって、「AND」ソートクエリはクライアント側で実行する必要があります)

このスタイルで配列を使用すると、同時書き込み用に最適化できます。これは素晴らしいことです。バッチリクエストをサポートしていることをテストしていません(ドキュメントは言いません)。


使用法:

collection("collectionPath").
    where("searchTermsArray", "array-contains", "term").get()
10
Albert Renshaw

Firestore docs ごとに、Cloud Firestoreはネイティブインデックス作成またはドキュメント内のテキストフィールドの検索をサポートしていません。また、コレクション全体をダウンロードしてクライアント側のフィールドを検索することは実用的ではありません。

AlgoliaElastic Search などのサードパーティの検索ソリューションをお勧めします。

6
bholben

遅い答えですが、まだ答えを探している人のために、ユーザーのコレクションがあり、コレクションの各ドキュメントに「ユーザー名」フィールドがあるので、ユーザー名が「al」で始まるドキュメントを見つけたいとしましょう私たちは次のようなことができます

 FirebaseFirestore.getInstance().collection("users").whereGreaterThanOrEqualTo("username", "al")
2
MoTahir

Firestore内でこれを行う最善の解決策は、実際にはすべてのサブストリングを配列に入れ、array_containsクエリを実行することだと思います。これにより、部分文字列の照合を行うことができます。すべての部分文字列を保存するのは少しやり過ぎですが、検索語が短い場合は非常に合理的です。

0
Dan Fein

私はちょうどこの問題を抱えていて、非常に簡単な解決策を思いつきました。

String search = "ca";
Firestore.instance.collection("categories").orderBy("name").where("name",isGreaterThanOrEqualTo: search).where("name",isLessThanOrEqualTo: search+"z")

IsGreaterThanOrEqualToを使用すると、検索の先頭を除外し、isLessThanOrEqualToの末尾に「z」を追加することで、次のドキュメントにロールオーバーしないように検索を制限できます。

0
Jacob Bonk