Google Firestore: consulta sobre la subcadena de un valor de propiedad (búsqueda de texto)

104

Estoy buscando agregar un campo de búsqueda simple, me gustaría usar algo como

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

Intenté usar where('name', '==', '%searchTerm%'), pero no devolvió nada.

tehfailsafe
fuente
2
Por favor, ha encontrado alguna solución. He estado buscando durante días algo similar sin falta
suulisin
1
Firebase ahora admite esto. Actualice la respuesta: stackoverflow.com/a/52715590/2057171
Albert Renshaw
1
Creo que la mejor manera es crear un script que indexe manualmente cada documento. Luego consulta esos índices. mira
Kiblawi_Rabee

Respuestas:

35

No hay tal operador, se admiten los son ==, <, <=, >, >=.

Puede filtrar solo por prefijos, por ejemplo, para todo lo que comienza entre bary foopuede usar

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

Puede usar un servicio externo como Algolia o ElasticSearch para eso.

Kuba
fuente
5
Eso no es exactamente lo que estoy buscando. Tengo una gran lista de productos con títulos largos. "Raqueta de tenis para hombre Rebok". Un usuario puede buscar tennis, pero según los operadores de consulta disponibles, no hay forma de obtener esos resultados. Combinando >=y <=no funciona. Por supuesto que puedo usar Algolia, pero también podría usarlo con Firebase para hacer la mayoría de las consultas y no necesito cambiar a Firestore ...
tehfailsafe
4
@tehfailsafe Bueno, tu pregunta es 'cómo consultar si un campo contiene una cadena', y la respuesta es 'no puedes hacer eso'.
Kuba
20
@ A.Chakroun, ¿qué es exactamente grosero en mi respuesta?
Kuba
18
tbh esto es algo realmente necesario. No puedo entender por qué el equipo de Firebase no pensó en esto
Dani
2
Realmente sorprende que Firebase sea tan débil en las consultas. No puedo creer que haya tanta gente usándolo si no puede admitir una consulta tan simple.
Bagusflyer
43

Si bien la respuesta de Kuba es cierta en lo que respecta a las restricciones, puede emular parcialmente esto con una estructura similar a un conjunto:

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

Ahora puedes consultar con

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

Esto funciona porque Firestore creará automáticamente un índice para cada campo. Desafortunadamente, esto no funciona directamente para consultas compuestas porque Firestore no crea índices compuestos automáticamente.

Todavía puede solucionar esto almacenando combinaciones de palabras, pero esto se pone feo rápidamente.

Probablemente aún esté mejor con una búsqueda de texto completo externa .

Gil Gilbert
fuente
¿Es posible utilizar la función de nube con cloud.google.com/appengine/docs/standard/java/search ?
Henry
1
Si está preguntando esto como seguimiento de esta respuesta, entonces: La búsqueda de texto completo de AppEngine está completamente separada de Firestore y, por lo tanto, esto no lo ayudará directamente. Puede replicar sus datos usando una función en la nube, pero esa es esencialmente la sugerencia para usar la búsqueda de texto completo externa. Si está preguntando algo más, inicie una nueva pregunta.
Gil Gilbert
1
En Firestore, debe indexar todos los términos antes de usarloswhere
Husam
4
Como mencionó Husam, todos estos campos deberían estar indexados. Quería habilitar la búsqueda de cualquier término que contenga el nombre de mi producto. Así que creé una propiedad de tipo 'objeto' en mi documento con claves que son partes del nombre del producto, cada una con un valor 'verdadero' asignado, con la esperanza de que buscar dónde ('nameSegments.tennis', '==', verdadero) funciona, pero firestore sugiere crear un índice para nameSegments.tennis, lo mismo para cualquier otro término. Dado que puede haber un número infinito de términos, esta respuesta solo se puede utilizar para un escenario muy limitado cuando todos los términos de búsqueda están definidos por adelantado.
Slawoj
2
@epeleg La consulta funcionaría, después de haber creado un índice para ella, pero no es factible crear un índice para cada término posible que contenga el nombre de su producto, por lo que para la búsqueda de texto de términos en nombres de productos, este enfoque no funcionó en mi caso.
Slawoj
43

Estoy de acuerdo con la respuesta de @ Kuba, pero aún así, debe agregar un pequeño cambio para que funcione perfectamente para la búsqueda por prefijo. aquí lo que funcionó para mí

Para buscar registros que comiencen con el nombre queryText

collectionRef.where('name', '>=', queryText).where('name', '<=', queryText+ '\uf8ff').

El carácter \uf8ffutilizado en la consulta es un punto de código muy alto en el rango Unicode (es un código de Área de uso privada [PUA]). Debido a que va después de la mayoría de los caracteres regulares en Unicode, la consulta coincide con todos los valores que comienzan con queryText.

Ankit Prajapati
fuente
1
¡Buena respuesta !, esto funciona muy bien para la búsqueda de texto de prefijo. Para buscar palabras en el texto, puede intentar la implementación "array-contains" como se explica en esta publicación medium.com/@ken11zer01/…
guillefd
Solo pienso, pero teóricamente podría hacer coincidir todos los valores que terminan con queryTest creando otro campo e invirtiendo los datos ...
Jonathan
Sí @Jonathan, eso también es posible.
Ankit Prajapati
30

Si bien Firebase no admite explícitamente la búsqueda de un término dentro de una cadena,

Firebase (ahora) admite lo siguiente que resolverá su caso y muchos otros:

A partir de agosto de 2018, admiten array-containsconsultas. Ver: https://firebase.googleblog.com/2018/08/better-arrays-in-cloud-firestore.html

Ahora puede establecer todos sus términos clave en una matriz como un campo y luego consultar todos los documentos que tienen una matriz que contiene 'X'. Puede utilizar AND lógico para realizar más comparaciones para consultas adicionales. (Esto se debe a que firebase actualmente no admite de forma nativa consultas compuestas para múltiples consultas que contienen matrices, por lo que las consultas de clasificación 'Y' deberán realizarse en el extremo del cliente)

El uso de matrices en este estilo permitirá que se optimicen para escrituras simultáneas, lo cual es bueno. No he probado que admita solicitudes por lotes (los documentos no lo dicen), pero apuesto a que sí, ya que es una solución oficial.


Uso:

collection("collectionPath").
    where("searchTermsArray", "array-contains", "term").get()
Albert Renshaw
fuente
12
Ésta es una buena solución. Sin embargo, corrígeme si me equivoco, pero creo que no te permite hacer lo que @tehfailsafe ha pedido. Por ejemplo, si desea obtener todos los nombres que contienen la cadena "abc", no obtendrá ningún éxito con array-contains, ya que solo devolverá los documentos que tengan el nombre exacto de "abc", pero "abcD" o "0abc" estaría fuera.
Yulian
1
@Yulian En el mundo de la programación, Search termse entiende típicamente como un término completo separado por espacio, puntuación, etc. en ambos lados. Si abcdebusca en Google en este momento, solo encontrará resultados para cosas como %20abcde.o ,abcde!pero no abcdefghijk... aunque seguramente todo el alfabeto escrito es mucho más común de encontrar en Internet, la búsqueda no es para abcde * es para un abcde aislado
Albert Renshaw
1
Veo su punto y estoy de acuerdo con él, pero probablemente la palabra me engañó 'contains', que significa exactamente a lo que me refiero en muchos lenguajes de programación. Lo mismo ocurre '%searchTerm%'desde el punto de vista de SQL.
Yulian
2
@Yulian Sí, lo entiendo. Sin embargo, Firebase es NoSQL, por lo que es realmente bueno para hacer que este tipo de operaciones sea rápido y eficiente, incluso si pueden estar limitadas para algunos problemas fuera de alcance, como la búsqueda de cadenas comodín.
Albert Renshaw
2
Bueno, podría crear un campo separado para cada uno con la representación de las palabras divididas como titleArray: ['esto', 'es', 'a', 'título'] cada vez que actualice el documento. Y luego la búsqueda se basará en ese campo en lugar del título. Puede crear un activador onUpdate para crear estos campos. Mucho trabajo para el texto basado en búsquedas, pero prefiero tener las mejoras de rendimiento de NoSQL.
sfratini
14

Según los documentos de Firestore , Cloud Firestore no admite la indexación nativa ni la búsqueda de campos de texto en los documentos. Además, descargar una colección completa para buscar campos en el lado del cliente no es práctico.

Se recomiendan soluciones de búsqueda de terceros como Algolia y Elastic Search .

bholben
fuente
46
He leído los documentos, aunque no es ideal. El inconveniente es que Algolia y Firestore tienen diferentes modelos de precios ... Puedo tener felizmente 600.000 documentos en Firestore (siempre que no consulte demasiados por día). Cuando los empujo a Algolia para buscar, ahora tengo que pagar a Algolia $ 310 por mes solo para poder hacer una búsqueda de título en mis documentos de Firestore.
tehfailsafe
2
el problema es que esto no es gratis
Dani
Ésta es la respuesta correcta a la pregunta planteada y debe aceptarse como la mejor.
briznad
11

Algunas notas aquí:

1.) \uf8ff funciona de la misma manera que~

2.) Puede utilizar una cláusula where o cláusulas start end:

ref.orderBy('title').startAt(term).endAt(term + '~');

es exactamente lo mismo que

ref.where('title', '>=', term).where('title', '<=', term + '~');

3.) No, no funciona si invierte startAt()y endAt()en todas las combinaciones, sin embargo, puede lograr el mismo resultado creando un segundo campo de búsqueda que se invierte y combinando los resultados.

Ejemplo: primero debe guardar una versión inversa del campo cuando se crea el campo. Algo como esto:

// collection
const postRef = db.collection('posts')

async function searchTitle(term) {

  // reverse term
  const termR = term.split("").reverse().join("");

  // define queries
  const titles = postRef.orderBy('title').startAt(term).endAt(term + '~').get();
  const titlesR = postRef.orderBy('titleRev').startAt(termR).endAt(termR + '~').get();

  // get queries
  const [titleSnap, titlesRSnap] = await Promise.all([
    titles,
    titlesR
  ]);
  return (titleSnap.docs).concat(titlesRSnap.docs);
}

Con esto, puede buscar las últimas letras de un campo de cadena y la primera , pero no letras intermedias o grupos de letras al azar. Esto está más cerca del resultado deseado. Sin embargo, esto realmente no nos ayudará cuando queremos letras o palabras medias al azar. Además, recuerde guardar todo en minúsculas, o una copia en minúsculas para buscar, para que el uso de mayúsculas y minúsculas no sea un problema.

4.) Si solo tiene unas pocas palabras, el método de Ken Tan hará todo lo que desee, o al menos después de modificarlo ligeramente. Sin embargo, con solo un párrafo de texto, creará exponencialmente más de 1 MB de datos, que es más grande que el límite de tamaño del documento de Firestore (lo sé, lo probé).

5.) Si pudiera combinar array-contains (o alguna forma de arrays) con el \uf8fftruco, podría tener una búsqueda viable que no alcance los límites. Probé todas las combinaciones, incluso con mapas, y no lo hice. Cualquiera que se dé cuenta de esto, publíquelo aquí.

6.) Si debes alejarte de ALGOLIA y ELASTIC SEARCH, y no te culpo en absoluto, siempre puedes usar mySQL, postSQL o neo4Js en Google Cloud. Son 3 fáciles de configurar y tienen niveles gratuitos. Tendría una función en la nube para guardar los datos onCreate () y otra función onCall () para buscar los datos. Simple ... ish. ¿Por qué no cambiar a mySQL entonces? ¡Los datos en tiempo real, por supuesto! Cuando alguien escribe DGraph con websocks para obtener datos en tiempo real, ¡cuenta conmigo!

Algolia y ElasticSearch se crearon para ser bases de datos de solo búsqueda, por lo que no hay nada tan rápido ... pero usted paga por ello. Google, ¿por qué nos alejas de Google y no sigues MongoDB noSQL y permites las búsquedas?

ACTUALIZACIÓN - CREÉ UNA SOLUCIÓN:

https://fireblog.io/blog/post/firestore-full-text-search

Jonathan
fuente
Una gran descripción general y muy útil.
RedFilter
¡Increíble! voto positivo para una respuesta bien estructurada e informativa.
King Of The Jungle
10

Respuesta tardía, pero para cualquiera que todavía esté buscando una respuesta, digamos que tenemos una colección de usuarios y en cada documento de la colección tenemos un campo de "nombre de usuario", así que si quieres encontrar un documento donde el nombre de usuario comience con "al" podemos hacer algo como

 FirebaseFirestore.getInstance().collection("users").whereGreaterThanOrEqualTo("username", "al")
MoTahir
fuente
esta es una gran solución fácil gracias. Pero, ¿qué sucede si desea marcar más de un campo? ¿Como "nombre" y "descripción" conectados por un OR?
Pruébelo el
No creo que pueda realizar consultas basadas en dos campos, lamentablemente firebase es malo cuando se trata de consultas, puede verificar esta esperanza de que ayude a stackoverflow.com/questions/26700924/…
MoTahir
1
Confirmado, @MoTahir. No hay "OR" en Firestore.
Rap
esa solución no coincide con los nombres de usuario que comienzan con "al" ... por ejemplo, "hola" coincidiría ("hola"> "al")
antoine129
La consulta por OR es simplemente una cuestión de combinar dos resultados de búsqueda. Ordenar esos resultados es un problema diferente ...
Jonathan
7

Estoy seguro de que Firebase saldrá pronto con "string-contains" para capturar cualquier índice [i] startAt en la cadena ... Pero investigué las web y encontré esta solución pensada por otra persona que configuró sus datos como esta

state = {title:"Knitting"}
...
const c = this.state.title.toLowerCase()

var array = [];
for (let i = 1; i < c.length + 1; i++) {
 array.push(c.substring(0, i));
}

firebase
.firestore()
.collection("clubs")
.doc(documentId)
.update({
 title: this.state.title,
 titleAsArray: array
})

ingrese la descripción de la imagen aquí

consulta como esta

firebase
.firestore()
.collection("clubs")
.where(
 "titleAsArray",
 "array-contains",
 this.state.userQuery.toLowerCase()
)
Nick Carducci
fuente
No recomendado en absoluto. Como los documentos tienen un límite de 20k líneas, no puede utilizarlos de esta manera, hasta que esté seguro de que su documento nunca alcanzará tales límites
Sandeep
Es la mejor opción en este momento, ¿qué más se recomienda?
Nick Carducci
1
@Sandeep Estoy bastante seguro de que el tamaño está limitado a 1 MB de tamaño y 20 niveles de profundidad por documento. ¿A qué te refieres con 20k líneas? Esta es actualmente la mejor solución si el uso de Algolia o ElasticSearch está fuera de la mesa
ppicom
5

Si no desea utilizar un servicio de terceros como Algolia, Firebase Cloud Functions es una excelente alternativa. Puede crear una función que pueda recibir un parámetro de entrada, procesar a través de los registros del lado del servidor y luego devolver los que coincidan con sus criterios.

Rap
fuente
1
¿Qué pasa con Android?
Pratik Butani
¿Propones que la gente repita cada registro de una colección?
DarkNeuron
Realmente no. Usaría Array.prototype. * - Como .every (), .some (), .map (), .filter (), etc. Esto se hace en Node en el servidor en una función de Firebase antes de devolver valores al cliente.
Rap
3
Aún tendría que leer TODOS los documentos para buscarlos, lo que incurre en gastos y es costoso para Time.
Jonathan
3

De hecho, creo que la mejor solución para hacer esto dentro de Firestore es poner todas las subcadenas en una matriz y simplemente hacer una consulta array_contains. Esto le permite hacer una coincidencia de subcadenas. Es un poco exagerado almacenar todas las subcadenas, pero si los términos de búsqueda son cortos, es muy razonable.

Dan Fein
fuente
2

Acabo de tener este problema y se me ocurrió una solución bastante simple.

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

IsGreaterThanOrEqualTo nos permite filtrar el comienzo de nuestra búsqueda y al agregar una "z" al final de isLessThanOrEqualTo limitamos nuestra búsqueda para no pasar a los siguientes documentos.

Jacob Bonk
fuente
3
Probé esta solución, pero para mí solo funciona cuando se ingresa la cadena completa. Por ejemplo, si quiero obtener el término "gratis", si empiezo a escribir "fr", no se devolverá nada. Una vez que escribo "gratis", el término me da su instantánea.
Chris
¿Estás usando el mismo formato de código? ¿Y el término es una cadena en firestore? Sé que no puede filtrar por documentId.
Jacob Bonk
2

La respuesta seleccionada solo funciona para búsquedas exactas y no es un comportamiento de búsqueda natural del usuario (la búsqueda de "manzana" en "Joe comió una manzana hoy" no funcionaría).

Creo que la respuesta de Dan Fein anterior debería tener una clasificación más alta. Si los datos de cadena que está buscando son cortos, puede guardar todas las subcadenas de la cadena en una matriz en su documento y luego buscar a través de la matriz con la consulta array_contains de Firebase. Los documentos de Firebase están limitados a 1 MiB (1.048.576 bytes) ( Cuotas y límites de Firebase ), que es aproximadamente 1 millón de caracteres guardados en un documento (creo que 1 carácter ~ = 1 byte). El almacenamiento de las subcadenas está bien siempre que su documento no se acerque a la marca de 1 millón.

Ejemplo para buscar nombres de usuario:

Paso 1: agregue la siguiente extensión de cadena a su proyecto. Esto le permite dividir fácilmente una cadena en subcadenas. ( Encontré esto aquí ).

extension String {

var length: Int {
    return count
}

subscript (i: Int) -> String {
    return self[i ..< i + 1]
}

func substring(fromIndex: Int) -> String {
    return self[min(fromIndex, length) ..< length]
}

func substring(toIndex: Int) -> String {
    return self[0 ..< max(0, toIndex)]
}

subscript (r: Range<Int>) -> String {
    let range = Range(uncheckedBounds: (lower: max(0, min(length, r.lowerBound)),
                                        upper: min(length, max(0, r.upperBound))))
    let start = index(startIndex, offsetBy: range.lowerBound)
    let end = index(start, offsetBy: range.upperBound - range.lowerBound)
    return String(self[start ..< end])
}

Paso 2: cuando almacena el nombre de un usuario, también almacena el resultado de esta función como una matriz en el mismo documento. Esto crea todas las variaciones del texto original y las almacena en una matriz. Por ejemplo, la entrada de texto "Apple" crearía la siguiente matriz: ["a", "p", "p", "l", "e", "ap", "pp", "pl", "le "," app "," ppl "," ple "," appl "," pple "," apple "], que debe abarcar todos los criterios de búsqueda que un usuario pueda ingresar. Puede dejar maximumStringSize como nulo si desea todos los resultados, sin embargo, si hay texto largo, recomendaría limitarlo antes de que el tamaño del documento sea demasiado grande; alrededor de 15 funciona bien para mí (la mayoría de las personas no buscan frases largas de todos modos ).

func createSubstringArray(forText text: String, maximumStringSize: Int?) -> [String] {

    var substringArray = [String]()
    var characterCounter = 1
    let textLowercased = text.lowercased()

    let characterCount = text.count
    for _ in 0...characterCount {
        for x in 0...characterCount {
            let lastCharacter = x + characterCounter
            if lastCharacter <= characterCount {
                let substring = textLowercased[x..<lastCharacter]
                substringArray.append(substring)
            }
        }
        characterCounter += 1

        if let max = maximumStringSize, characterCounter > max {
            break
        }
    }

    print(substringArray)
    return substringArray
}

Paso 3: ¡Puedes usar la función array_contains de Firebase!

[yourDatabasePath].whereField([savedSubstringArray], arrayContains: searchText).getDocuments....
pan puro
fuente
0

Con Firestore puede implementar una búsqueda de texto completo, pero aún costará más lecturas de las que tendría de otra manera, y también deberá ingresar e indexar los datos de una manera particular, por lo que en este enfoque puede usar las funciones de la nube de firebase para tokenise y luego hash su texto de entrada mientras elige una función hash lineal h(x)que satisfaga lo siguiente: if x < y < z then h(x) < h (y) < h(z). Para la tokenización, puede elegir algunas bibliotecas ligeras de PNL para mantener bajo el tiempo de inicio en frío de su función que puede eliminar palabras innecesarias de su oración. Luego, puede ejecutar una consulta con un operador menor que y mayor que en Firestore. Mientras también almacena sus datos, tendrá que asegurarse de aplicar hash al texto antes de almacenarlo, y almacenar el texto sin formato también, como si cambiara el texto sin formato, el valor hash también cambiará.

Adarsh ​​Srivastava
fuente
0

Esto funcionó perfectamente para mí, pero podría causar problemas de rendimiento.

Haga esto al consultar firestore:

   Future<QuerySnapshot> searchResults = collectionRef
        .where('property', isGreaterThanOrEqualTo: searchQuery.toUpperCase())
        .getDocuments();

Haga esto en su FutureBuilder:

    return FutureBuilder(
          future: searchResults,
          builder: (context, snapshot) {           
            List<Model> searchResults = [];
            snapshot.data.documents.forEach((doc) {
              Model model = Model.fromDocumet(doc);
              if (searchQuery.isNotEmpty &&
                  !model.property.toLowerCase().contains(searchQuery.toLowerCase())) {
                return;
              }

              searchResults.add(model);
            })
   };
Arun Yogeshwaran
fuente
0

A día de hoy, existen básicamente 3 soluciones alternativas, que fueron sugeridas por los expertos, como respuestas a la pregunta.

Los he probado todos. Pensé que podría ser útil documentar mi experiencia con cada uno de ellos.

Método-A: Usando: (dbField "> =" searchString) & (dbField "<=" searchString + "\ uf8ff")

Sugerido por @Kuba & @Ankit Prajapati

.where("dbField1", ">=", searchString)
.where("dbField1", "<=", searchString + "\uf8ff");

A.1 Las consultas de Firestore solo pueden realizar filtros de rango (>, <,> =, <=) en un solo campo. No se admiten consultas con filtros de rango en varios campos. Al usar este método, no puede tener un operador de rango en ningún otro campo de la base de datos, por ejemplo, un campo de fecha.

A.2. Este método NO funciona para buscar en varios campos al mismo tiempo. Por ejemplo, no puede verificar si una cadena de búsqueda está en alguno de los archivos (nombre, notas y dirección).

Método B: usar un MAPA de cadenas de búsqueda con "verdadero" para cada entrada en el mapa y usar el operador "==" en las consultas

Sugerido por @Gil Gilbert

document1 = {
  'searchKeywordsMap': {
    'Jam': true,
    'Butter': true,
    'Muhamed': true,
    'Green District': true,
    'Muhamed, Green District': true,
  }
}

.where(`searchKeywordsMap.${searchString}`, "==", true);

B.1 Obviamente, este método requiere procesamiento adicional cada vez que se guardan datos en la base de datos y, lo que es más importante, requiere espacio adicional para almacenar el mapa de cadenas de búsqueda.

B.2 Si una consulta de Firestore tiene una condición única como la anterior, no es necesario crear un índice de antemano. Esta solución funcionaría bien en este caso.

B.3 Sin embargo, si la consulta tiene otra condición, por ejemplo (estado === "activo"), parece que se requiere un índice para cada "cadena de búsqueda" que ingresa el usuario. En otras palabras, si un usuario busca "Mermelada" y otro usuario busca "Mantequilla", se debe crear un índice de antemano para la cadena "Mermelada" y otro para "Mantequilla", etc. A menos que pueda predecir todo lo posible cadenas de búsqueda de los usuarios, esto NO funciona, ¡en caso de que la consulta tenga otras condiciones!

.where(searchKeywordsMap["Jam"], "==", true); // requires an index on searchKeywordsMap["Jam"]
.where("status", "==", "active");

** Método-C: usando un ARRAY de cadenas de búsqueda y el operador "array-contains"

Sugerido por @Albert Renshaw y demostrado por @Nick Carducci

document1 = {
  'searchKeywordsArray': [
    'Jam',
    'Butter',
    'Muhamed',
    'Green District',
    'Muhamed, Green District',
  ]
}

.where("searchKeywordsArray", "array-contains", searchString); 

C.1 Similar al Método B, este método requiere un procesamiento adicional cada vez que se guardan datos en la base de datos y, lo que es más importante, requiere espacio adicional para almacenar la matriz de cadenas de búsqueda.

C.2 Las consultas de Firestore pueden incluir como máximo una cláusula "array-contains" o "array-contains-any" en una consulta compuesta.

Limitaciones generales:

  1. Ninguna de estas soluciones parece admitir la búsqueda de cadenas parciales. Por ejemplo, si un campo db contiene "1 Peter St, Green District", no puede buscar la cadena "estricto".
  2. Es casi imposible cubrir todas las combinaciones posibles de cadenas de búsqueda esperadas. Por ejemplo, si un campo de base de datos contiene "1 Mohamed St, Green District", es posible que NO pueda buscar la cadena "Green Mohamed", que es una cadena que tiene las palabras en un orden diferente al que se utiliza en la base de datos. campo.

No existe una solución única que se adapte a todos. Cada solución alternativa tiene sus limitaciones. Espero que la información anterior pueda ayudarlo durante el proceso de selección entre estas soluciones.

Para obtener una lista de las condiciones de consulta de Firestore, consulte la documentación https://firebase.google.com/docs/firestore/query-data/queries .

No he probado https://fireblog.io/blog/post/firestore-full-text-search , que es sugerido por @Jonathan.

Bilal Abdeen
fuente
-10

Podemos usar la marca inversa para imprimir el valor de una cadena. Esto debería funcionar:

where('name', '==', `${searchTerm}`)
Zach J
fuente
Gracias, pero esta pregunta se trata de obtener valores no exactos. Por ejemplo, el ejemplo en cuestión funciona para encontrar si el nombre es exacto. Si tengo un documento con el nombre: "Prueba" y luego busco "Prueba", funciona. Pero esperaría poder buscar "tes" o "est" y aún así obtener el resultado de "Prueba". Imagine un caso de uso con títulos de libros. La gente suele buscar títulos de libros parciales en lugar del título exacto por completo.
tehfailsafe
13
@suulisin tienes razón, no lo leí con atención porque estaba ansioso por compartir lo que había encontrado. Gracias por su esfuerzo para señalar eso, y seré más cuidadoso
Zach J