Google Firestore: consulta sobre substring de um valor de propriedade (pesquisa de texto)

104

Estou tentando adicionar um campo de pesquisa simples, gostaria de usar algo como

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

Tentei usar where('name', '==', '%searchTerm%'), mas não retornou nada.

tehfailsafe
fonte
2
plesase você encontrou alguma solução. Tenho procurado há dias por algo semelhante sem falta
suulisin
1
Firebase agora oferece suporte para isso. Atualize a resposta: stackoverflow.com/a/52715590/2057171
Albert Renshaw,
1
Acho que a melhor maneira é criar um script que indexe manualmente cada documento. Em seguida, consulte esses índices. confira: angularfirebase.com/lessons/…
Kiblawi_Rabee

Respostas:

35

Não há tal operador, aqueles permitidos são ==, <, <=, >, >=.

Você pode filtrar por prefixos apenas, por exemplo, para tudo que começa entre bare foovocê pode usar

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

Você pode usar um serviço externo como Algolia ou ElasticSearch para isso.

Kuba
fonte
5
Não é bem isso que estou procurando. Tenho uma grande lista de produtos com títulos longos. "Raquete de tênis Rebok Mens". Um usuário pode pesquisar tennis, mas com base nos operadores de consulta disponíveis, não há como obter esses resultados. Combinando >=e <=não funciona. Claro que posso usar o Algolia, mas também poderia usá-lo com o Firebase para fazer a maioria das consultas e não precisar mudar para o Firestore ...
tehfailsafe
4
@tehfailsafe Bem, sua pergunta é 'como consultar se um campo contém uma string', e a resposta é 'você não pode fazer isso'.
Kuba
20
@ A.Chakroun o que exatamente é rude em minha resposta?
Kuba
18
tbh isso é algo realmente necessário. Não consigo entender por que a equipe do Firebase não pensou nisso
Dani,
2
Realmente é surpresa que o Firebase seja tão fraco em consultas. Não posso acreditar que há tantas pessoas usando-o se ele não suporta uma consulta tão simples.
Bagusflyer
43

Embora a resposta de Kuba seja verdadeira no que diz respeito às restrições, você pode emular isso parcialmente com uma estrutura semelhante a um conjunto:

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

Agora você pode consultar com

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

Isso funciona porque o Firestore criará automaticamente um índice para cada campo. Infelizmente, isso não funciona diretamente para consultas compostas porque o Firestore não cria índices compostos automaticamente.

Você ainda pode contornar isso armazenando combinações de palavras, mas isso fica feio rápido.

Provavelmente, você ainda está melhor com uma pesquisa de texto completa externa .

Gil Gilbert
fonte
É possível usar a função de nuvem com cloud.google.com/appengine/docs/standard/java/search ?
Henry,
1
Se você está perguntando isso como um seguimento a esta resposta, então: A pesquisa de texto completo do AppEngine é completamente separada do Firestore e, portanto, isso não o ajudará diretamente. Você poderia replicar seus dados usando uma função de nuvem, mas essa é essencialmente a sugestão de usar a pesquisa de texto completa externa. Se você está perguntando outra coisa, comece uma nova pergunta.
Gil Gilbert
1
No Firestore, você precisa indexar todos os termos antes de usarwhere
Husam
4
Como Husam mencionou, todos esses campos precisariam ser indexados. Eu queria permitir a pesquisa de qualquer termo que meu nome de produto contenha. Então eu criei uma propriedade de tipo 'objeto' no meu documento com as chaves sendo partes do nome do produto, cada uma com o valor 'true' atribuído a ela, esperando que a pesquisa onde ('nameSegments.tennis', '==', true) fosse funciona, mas o firestore sugere a criação de um índice para nameSegments.tennis, o mesmo para todos os outros termos. Como pode haver um número infinito de termos, essa resposta só pode ser usada em um cenário muito limitado, quando todos os termos de pesquisa são definidos antecipadamente.
Slawoj
2
@epeleg A consulta funcionaria, depois de criar um índice para ela, mas não é viável criar índice para cada termo possível que seu nome de produto contém, portanto, para pesquisa de texto de termos em nomes de produtos, essa abordagem não funcionou no meu caso.
Slawoj
43

Eu concordo com a resposta de @Kuba, mas ainda assim, é necessário adicionar uma pequena alteração para funcionar perfeitamente para pesquisa por prefixo. aqui o que funcionou para mim

Para pesquisar registros começando com o nome queryText

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

O caractere \uf8ffusado na consulta é um ponto de código muito alto no intervalo Unicode (é um código de área de uso privado [PUA]). Como ocorre após a maioria dos caracteres regulares em Unicode, a consulta corresponde a todos os valores que começam com queryText.

Ankit Prajapati
fonte
1
Boa resposta !, isso funciona muito bem para pesquisa de texto de prefixo. Para pesquisar palavras no texto, pode tentar a implementação "array-contains" conforme explicado neste post medium.com/@ken11zer01/…
guillefd
Só pensando, mas teoricamente você poderia combinar todos os valores que terminam com queryTest criando outro campo e invertendo os dados ...
Jonathan
Sim @Jonathan, isso também é possível.
Ankit Prajapati
30

Embora o Firebase não suporte explicitamente a pesquisa de um termo em uma string,

O Firebase (agora) oferece suporte ao seguinte, o que resolverá o seu caso e muitos outros:

Desde agosto de 2018, eles suportam array-containsconsultas. Veja: https://firebase.googleblog.com/2018/08/better-arrays-in-cloud-firestore.html

Agora você pode definir todos os seus termos-chave em uma matriz como um campo e, em seguida, consultar todos os documentos que possuem uma matriz que contém 'X'. Você pode usar o AND lógico para fazer comparações adicionais para consultas adicionais. (Isso ocorre porque o firebase atualmente não oferece suporte nativo a consultas compostas para várias consultas array-contains, portanto, as consultas de classificação 'AND' terão que ser feitas no lado do cliente)

Usar arrays neste estilo permitirá que eles sejam otimizados para gravações simultâneas, o que é bom! Não testei se ele oferece suporte a solicitações em lote (os documentos não dizem), mas aposto que sim, pois é uma solução oficial.


Uso:

collection("collectionPath").
    where("searchTermsArray", "array-contains", "term").get()
Albert Renshaw
fonte
12
Esta é uma boa solução. No entanto, corrija-me se eu estiver errado, mas acho que não permite que você faça o que @tehfailsafe pediu. Por exemplo, se você deseja obter todos os nomes que contenham a string "abc", você não obterá nenhum sucesso com array-contains, pois ele retornará apenas os documentos que têm o nome exato de "abc", mas "abcD" ou "0abc" estaria fora.
Yulian
1
@Yulian No mundo da programação, Search termnormalmente é entendido como um termo inteiro separado por espaço, pontuação, etc. em ambos os lados. Se você pesquisar no Google abcdeagora, só encontrará resultados para coisas como %20abcde.ou ,abcde!mas não abcdefghijk... embora certamente todo o alfabeto digitado seja muito mais comum de ser encontrado na internet, a busca não é por abcde * é por um abcde isolado
Albert Renshaw
1
Eu entendo seu ponto de vista e concordo com ele, mas provavelmente fui enganado pela palavra 'contains', que significa exatamente o que estou me referindo em muitas linguagens de programação. O mesmo se '%searchTerm%'aplica do ponto de vista SQL.
Yulian,
2
@Yulian Sim, eu entendo. No entanto, o Firebase é NoSQL, então é muito bom em tornar esses tipos de operações rápidas e eficientes, mesmo que eles possam ser limitados para alguns problemas fora do escopo, como pesquisa de string curinga.
Albert Renshaw,
2
Bem, você poderia criar um campo separado para cada um com a representação das palavras divididas como titleArray: ['this', 'is', 'a', 'title'] toda vez que você atualizar o documento. E então a pesquisa será baseada naquele campo em vez do título. Você pode criar um triiger onUpdate para criar esses campos. Muito trabalho para texto baseado em pesquisa, mas prefiro as melhorias de desempenho do NoSQL.
sfratini 01 de
14

De acordo com os documentos do Firestore , o Cloud Firestore não oferece suporte para indexação nativa ou pesquisa de campos de texto em documentos. Além disso, baixar uma coleção inteira para pesquisar campos do lado do cliente não é prático.

Soluções de pesquisa de terceiros como Algolia e Elastic Search são recomendadas.

Bholben
fonte
46
Eu li os documentos, embora não seja o ideal. A desvantagem é que Algolia e Firestore têm modelos de preços diferentes ... Posso felizmente ter 600.000 documentos no Firestore (contanto que não consulte muitos por dia). Quando eu os empurro para Algolia a fim de pesquisar, agora tenho que pagar a Algolia $ 310 por mês apenas para poder fazer uma pesquisa de títulos em meus documentos Firestore.
tehfailsafe
2
o problema é que isso não é de graça
Dani,
Esta é a resposta correta à pergunta feita e deve ser aceita como a melhor.
briznad
11

Algumas notas aqui:

1.) \uf8ff funciona da mesma maneira que~

2.) Você pode usar uma cláusula where ou cláusulas start end:

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

é exatamente o mesmo que

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

3.) Não, não funciona se você inverter startAt()e endAt()em todas as combinações, no entanto, você pode obter o mesmo resultado criando um segundo campo de pesquisa que é invertido e combinando os resultados.

Exemplo: primeiro você deve salvar uma versão reversa do campo quando o campo é criado. Algo assim:

// 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);
}

Com isso, você pode pesquisar as últimas letras de um campo de string e as primeiras , não apenas letras do meio aleatórias ou grupos de letras. Isso está mais próximo do resultado desejado. No entanto, isso não vai realmente nos ajudar quando queremos letras do meio ou palavras aleatórias. Além disso, lembre-se de salvar tudo em letras minúsculas ou uma cópia em minúsculas para pesquisa, para que a capitalização não seja um problema.

4.) Se você tiver apenas algumas palavras, o Método de Ken Tan fará tudo o que você quiser, ou pelo menos depois de modificá-lo ligeiramente. No entanto, com apenas um parágrafo de texto, você criará exponencialmente mais de 1 MB de dados, que é maior do que o limite de tamanho do documento do firestore (eu sei, eu testei).

5.) Se você pudesse combinar o array-contém (ou alguma forma de arrays) com o \uf8fftruque, você poderia ter uma busca viável que não alcança os limites. Tentei todas as combinações, mesmo com mapas, e não consegui. Se alguém descobrir isso, poste aqui.

6.) Se você precisa se afastar da ALGOLIA e do ELASTIC SEARCH, e eu não culpo você de forma alguma, você sempre pode usar mySQL, postSQL ou neo4Js no Google Cloud. São três fáceis de configurar e têm níveis gratuitos. Você teria uma função de nuvem para salvar os dados onCreate () e outra função onCall () para pesquisar os dados. Simples ... ish. Por que não mudar para o mySQL então? Os dados em tempo real, é claro! Quando alguém escreve DGraph com websocks para dados em tempo real, conte comigo!

Algolia e ElasticSearch foram construídos para serem bancos de dados somente para pesquisa, então não há nada tão rápido ... mas você paga por isso. Google, por que você nos afasta do Google e não segue o MongoDB noSQL e permite pesquisas?

ATUALIZAÇÃO - CRIEI UMA SOLUÇÃO:

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

Jonathan
fonte
Uma ótima visão geral e muito útil.
RedFilter
Impressionante! voto positivo para uma resposta bem estruturada e informativa.
King Of The Jungle
10

Resposta tardia, mas para quem ainda está procurando uma resposta, digamos que temos uma coleção de usuários e em cada documento da coleção temos um campo "nome de usuário", portanto, se quiser encontrar um documento onde o nome de usuário comece com "al" podemos fazer algo como

 FirebaseFirestore.getInstance().collection("users").whereGreaterThanOrEqualTo("username", "al")
MoTahir
fonte
esta é uma ótima solução fácil, obrigado. Mas e se você quiser verificar mais de um campo. Como "nome" e "descrição" conectados por um OU?
Experimente
Eu não acho que você pode consultar com base em dois campos, infelizmente, firebase é ruim quando se trata de consultar, você pode verificar isso espero que ajude stackoverflow.com/questions/26700924/…
MoTahir
1
Confirmado, @MoTahir. Não há "OR" no Firestore.
Rap de
essa solução não corresponde a nomes de usuários começando com "al" ... por exemplo, "hello" seria correspondido ("hello"> "al")
antoine129
Consultar por OR é simplesmente uma questão de combinar dois resultados de pesquisa. Classificar esses resultados é um problema diferente ...
Jonathan
7

Tenho certeza de que o Firebase sairá com "string-contém" em breve para capturar qualquer índice [i] startAt na string ... Mas eu pesquisei as redes e encontrei esta solução pensada por outra pessoa para configurar seus dados como isto

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
})

insira a descrição da imagem aqui

consulta como esta

firebase
.firestore()
.collection("clubs")
.where(
 "titleAsArray",
 "array-contains",
 this.state.userQuery.toLowerCase()
)
Nick Carducci
fonte
Nem um pouco recomendado. Como os documentos têm limite de 20 mil linhas, você não pode utilizá-los dessa forma, até ter certeza de que seu documento nunca alcançará esses limites
Sandeep
É a melhor opção no momento, o que mais é recomendado?
Nick Carducci
1
@Sandeep Tenho certeza de que o tamanho é limitado a 1 MB e 20 níveis de profundidade por documento. O que você quer dizer com 20 mil linhas? Esta é atualmente a melhor solução alternativa se o uso de Algolia ou ElasticSearch estiver fora de questão
ppicom
5

Se você não quiser usar um serviço de terceiros como o Algolia, o Firebase Cloud Functions é uma ótima alternativa. Você pode criar uma função que pode receber um parâmetro de entrada, processar os registros do lado do servidor e retornar aqueles que correspondem aos seus critérios.

Rap
fonte
1
E o Android?
Pratik Butani
Você está propondo que as pessoas iterem cada registro de uma coleção?
DarkNeuron
Na verdade não. Eu usaria Array.prototype. * - Como .every (), .some (), .map (), .filter (), etc. Isso é feito em Node no servidor em uma função Firebase antes de retornar valores para o cliente.
Rap
3
Você ainda teria que ler TODOS os documentos para pesquisá-los, o que acarreta despesas e é caro para o Time.
Jonathan
3

Na verdade, acho que a melhor solução para fazer isso no Firestore é colocar todas as substrings em uma matriz e apenas fazer uma consulta array_contains. Isso permite que você faça correspondência de substring. Um pouco exagerado armazenar todas as substrings, mas se seus termos de pesquisa forem curtos, é muito razoável.

Dan Fein
fonte
2

Acabei de ter esse problema e encontrei uma solução bem simples.

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

O isGreaterThanOrEqualTo nos permite filtrar o início de nossa pesquisa e, adicionando um "z" ao final de isLessThanOrEqualTo, limitamos nossa pesquisa para não passar para os próximos documentos.

Jacob Bonk
fonte
3
Eu tentei esta solução, mas para mim ela só funciona quando a string completa é inserida. Por exemplo, se eu quiser obter o termo "grátis", se eu começar a digitar "fr", nada retornará. Depois que eu digito "grátis", o termo me fornece um instantâneo.
Chris
Você está usando o mesmo formato de código? E o termo é uma string no firestore? Eu sei que você não pode filtrar pelo documentId.
Jacob Bonk
2

A resposta selecionada só funciona para pesquisas exatas e não é um comportamento de pesquisa natural do usuário (pesquisar "maçã" em "João comeu uma maçã hoje" não funcionaria).

Acho que a resposta de Dan Fein acima deveria ser classificada em posição superior. Se os dados da String que você está pesquisando forem curtos, você pode salvar todas as substrings da string em uma matriz em seu Documento e, em seguida, pesquisar na matriz com a consulta array_contains do Firebase. Os documentos do Firebase são limitados a 1 MiB (1.048.576 bytes) ( cotas e limites do Firebase ), o que corresponde a cerca de 1 milhão de caracteres salvos em um documento (acho que 1 caractere ~ = 1 byte). Não há problema em armazenar substrings, desde que o documento não esteja perto da marca de 1 milhão.

Exemplo para pesquisar nomes de usuário:

Etapa 1: adicione a seguinte extensão String ao seu projeto. Isso permite que você divida facilmente uma string em substrings. ( Eu encontrei isso aqui ).

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])
}

Etapa 2: Ao armazenar o nome de um usuário, armazene também o resultado desta função como uma matriz no mesmo Documento. Isso cria todas as variações do texto original e as armazena em uma matriz. Por exemplo, a entrada de texto "Apple" criaria a seguinte matriz: ["a", "p", "p", "l", "e", "ap", "pp", "pl", "le "," app "," ppl "," ple "," appl "," pple "," apple "], que deve abranger todos os critérios de pesquisa que um usuário pode inserir. Você pode deixar maximumStringSize como nulo se quiser todos os resultados, no entanto, se houver texto longo, eu recomendaria limitá-lo antes que o tamanho do documento fique muito grande - algo em torno de 15 funciona bem para mim (a maioria das pessoas não pesquisa frases longas de qualquer maneira )

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
}

Etapa 3: você pode usar a função array_contains do Firebase!

[yourDatabasePath].whereField([savedSubstringArray], arrayContains: searchText).getDocuments....
pão puro
fonte
0

Com o Firestore, você pode implementar uma pesquisa de texto completo, mas ainda custará mais leituras do que teria de outra forma, e você também precisará inserir e indexar os dados de uma maneira particular. Portanto, nesta abordagem, você pode usar as funções de nuvem do Firebase para tokenize e, em seguida, hash seu texto de entrada ao escolher uma função hash linear h(x)que satisfaça o seguinte - if x < y < z then h(x) < h (y) < h(z). Para tokenização, você pode escolher algumas Bibliotecas de PNL leves para manter o tempo de inicialização a frio de sua função baixo, o que pode retirar palavras desnecessárias de sua frase. Em seguida, você pode executar uma consulta com menor que e maior que operador no Firestore. Ao armazenar seus dados também, você terá que certificar-se de fazer o hash do texto antes de armazená-lo, e armazenar o texto simples também como se você alterasse o texto simples, o valor hash também mudaria.

Adarsh ​​Srivastava
fonte
0

Isso funcionou perfeitamente para mim, mas pode causar problemas de desempenho.

Faça isso ao consultar o firestore:

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

Faça isso no seu 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
fonte
0

A partir de hoje, existem basicamente 3 soluções alternativas diferentes, que foram sugeridas pelos especialistas, como respostas à pergunta.

Eu tentei todos eles. Achei que seria útil documentar minha experiência com cada um deles.

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

Sugerido por @Kuba e @Ankit Prajapati

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

A.1 As consultas do Firestore só podem realizar filtros de intervalo (>, <,> =, <=) em um único campo. Não há suporte para consultas com filtros de intervalo em vários campos. Usando este método, você não pode ter um operador de intervalo em qualquer outro campo no banco de dados, por exemplo, um campo de data.

A.2. Este método NÃO funciona para pesquisar em vários campos ao mesmo tempo. Por exemplo, você não pode verificar se uma string de pesquisa está em algum dos campos (nome, notas e endereço).

Método B: usando um MAP de strings de pesquisa com "true" para cada entrada no mapa e usando o operador "==" nas 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, esse método requer processamento extra sempre que os dados são salvos no banco de dados e, mais importante, requer espaço extra para armazenar o mapa de strings de pesquisa.

B.2 Se uma consulta do Firestore tem uma única condição como a acima, nenhum índice precisa ser criado de antemão. Esta solução funcionaria muito bem neste caso.

B.3 No entanto, se a consulta tiver outra condição, por exemplo (status === "ativo"), parece que um índice é necessário para cada "string de pesquisa" que o usuário inserir. Em outras palavras, se um usuário pesquisar por "Jam" e outro usuário pesquisar por "Butter", um índice deve ser criado com antecedência para a string "Jam" e outro para "Butter", etc. A menos que você possa prever todas as possibilidades strings de pesquisa dos usuários, isso NÃO funciona - caso a consulta tenha outras condições!

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

** Método C: usando um ARRAY de strings de pesquisa e o operador "array-contém"

Sugerido por @Albert Renshaw e demonstrado por @Nick Carducci

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

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

C.1 Semelhante ao Método-B, este método requer processamento extra toda vez que os dados são salvos no banco de dados e, mais importante, requer espaço extra para armazenar a matriz de strings de pesquisa.

C.2 As consultas do Firestore podem incluir no máximo uma cláusula "array-contém" ou "array-contém-qualquer" em uma consulta composta.

Limitações gerais:

  1. Nenhuma dessas soluções parece oferecer suporte à pesquisa de strings parciais. Por exemplo, se um campo db contém "1 Peter St, Green District", você não pode pesquisar a string "strict".
  2. É quase impossível cobrir todas as combinações possíveis de strings de pesquisa esperadas. Por exemplo, se um campo de banco de dados contém "1 Mohamed St, Green District", você NÃO pode pesquisar a string "Green Mohamed", que é uma string com palavras em uma ordem diferente da ordem usada no banco de dados campo.

Não existe uma solução que sirva para todos. Cada solução alternativa tem suas limitações. Espero que as informações acima possam ajudá-lo durante o processo de seleção entre essas soluções alternativas.

Para obter uma lista das condições de consulta do Firestore, verifique a documentação https://firebase.google.com/docs/firestore/query-data/queries .

Não tentei https://fireblog.io/blog/post/firestore-full-text-search , que é sugerido por @Jonathan.

Bilal Abdeen
fonte
-10

Podemos usar o back-tick para imprimir o valor de uma string. Isso deve funcionar:

where('name', '==', `${searchTerm}`)
Zach J
fonte
Obrigado, mas esta questão é sobre como obter valores não exatos. Por exemplo, o exemplo em questão funciona para descobrir se o nome é exato. Se eu tenho um documento com o nome: "Teste" e procuro por "Teste", funciona. Mas eu esperaria conseguir pesquisar por "tes" ou "est" e ainda obter o resultado "Teste". Imagine um caso de uso com títulos de livros. Freqüentemente, as pessoas procuram títulos parciais de livros, em vez de apenas o título preciso.
tehfailsafe
13
@suulisin você está certo, não li atentamente porque estava ansioso para compartilhar o que havia encontrado. Obrigado pelo seu esforço em apontar isso e serei mais cuidadoso
Zach J