Je cherche à ajouter un champ de recherche simple, j'aimerais utiliser quelque chose comme
collectionRef.where('name', 'contains', 'searchTerm')
J'ai essayé d'utiliser where('name', '==', '%searchTerm%')
, mais cela ne m'a rien retourné.
Il n'y a pas d'opérateur de ce type, ceux autorisés sont ==
, <
, <=
, >
, >=
.
Vous ne pouvez filtrer que par préfixes, par exemple pour tout ce qui commence entre bar
et foo
, vous pouvez utiliser
collectionRef.where('name', '>=', 'bar').where('name', '<=', 'foo')
Vous pouvez utiliser un service externe comme Algolia ou ElasticSearch pour cela.
Bien que la réponse de Kuba soit vraie en ce qui concerne les restrictions, vous pouvez partiellement l'imiter avec une structure en ensembles:
{
'terms': {
'reebok': true,
'mens': true,
'tennis': true,
'racket': true
}
}
Maintenant, vous pouvez interroger avec
collectionRef.where('terms.tennis', '==', true)
Cela fonctionne car Firestore créera automatiquement un index pour chaque champ. Malheureusement, cela ne fonctionne pas directement pour les requêtes composées car Firestore ne crée pas automatiquement d'index composites.
Vous pouvez toujours contourner ce problème en stockant des combinaisons de mots, mais cela devient très vite moche.
Vous êtes probablement encore mieux avec un hors-bord recherche en texte intégral .
Firebase ne prend pas explicitement en charge la recherche d'un terme dans une chaîne ...
Firebase prend toutefois en charge les éléments suivants, qui résoudront pour votre cas et bien d’autres:
Depuis août 2018, ils prennent en charge la requête array-contains
. Voir: https://firebase.googleblog.com/2018/08/better-arrays-in-cloud-firestore.html
Vous pouvez maintenant définir tous vos termes clés dans un tableau en tant que champ, puis interroger tous les documents contenant un tableau contenant "X". Vous pouvez utiliser AND logique pour effectuer des comparaisons supplémentaires pour requêtes supplémentaires. (En effet, firebase ne prend actuellement pas en charge de manière native les requêtes composées pour plusieurs requêtes contenant un tableau les requêtes de tri 'AND' devront donc être effectuées côté client)
L'utilisation de tableaux dans ce style leur permettra d'être optimisés pour les écritures simultanées, ce qui est agréable! Je n'ai pas testé le support des requêtes batch (les documents ne le disent pas), mais je parierais que c'est une solution officielle.
collection("collectionPath").
where("searchTermsArray", "array-contains", "term").get()
Conformément à Firestore docs , Cloud Firestore ne prend pas en charge l'indexation native ni la recherche de champs de texte dans les documents. De plus, le téléchargement d'une collection complète pour rechercher des champs côté client n'est pas pratique.
Les solutions de recherche tierces telles que Algolia et Elastic Search sont recommandées.
Réponse tardive, mais pour ceux qui cherchent encore une réponse, supposons que nous avons une collection d'utilisateurs et que dans chaque document de la collection, nous avons un champ "nom d'utilisateur", donc si vous voulez trouver un document dont le nom d'utilisateur commence par "al" nous pouvons faire quelque chose comme
FirebaseFirestore.getInstance().collection("users").whereGreaterThanOrEqualTo("username", "al")
Je suis d’accord avec la réponse de @ Kuba, mais elle doit quand même ajouter un petit changement pour fonctionner parfaitement pour la recherche par préfixe. voici ce qui a fonctionné pour moi
Pour rechercher des notices commençant par le nom queryText
collectionRef.where('name', '>=', queryText).where('name', '<=', queryText+ '\uf8ff')
.
Le caractère \uf8ff
utilisé dans la requête est un point de code très élevé dans la plage Unicode (il s'agit d'un code de zone d'utilisation privée [PUA]). Comme c'est après la plupart des caractères normaux dans Unicode, la requête correspond à toutes les valeurs commençant par queryText
.
Je viens d'avoir ce problème et proposé une solution assez simple.
String search = "ca";
Firestore.instance.collection("categories").orderBy("name").where("name",isGreaterThanOrEqualTo: search).where("name",isLessThanOrEqualTo: search+"z")
IsGreaterThanOrEqualTo nous permet de filtrer le début de notre recherche et en ajoutant un "z" à la fin de la valeur isLessThanOrEqualTo afin de limiter notre recherche à un autre point.
Si vous ne souhaitez pas utiliser un service tiers comme Algolia, les services fonctions cloud de Firebase constituent une excellente alternative. Vous pouvez créer une fonction pouvant recevoir un paramètre d'entrée, traiter via les enregistrements côté serveur, puis renvoyer ceux qui correspondent à vos critères.
En fait, je pense que la meilleure solution dans Firestore consiste à placer toutes les sous-chaînes dans un tableau et à effectuer une requête array_contains. Cela vous permet de faire une correspondance de sous-chaîne. Un peu exagéré pour stocker toutes les sous-chaînes, mais si vos termes de recherche sont courts, c'est très très raisonnable.