Texto de pesquisa
Nesta página
Visão geral
As pesquisas de texto permitem pesquisar em campos do tipo string em sua coleção por palavras ou frases especificadas. Você pode realizar uma pesquisa de texto usando o operador $text
, que executa um OR
lógico em cada termo separado por um espaço na string de pesquisa. Você também pode especificar mais opções para o operador lidar com diferenciação de maiúsculas e minúsculas, palavras de parada e derivação de palavras (como formas plurais ou outros tempos) para um idioma com suporte. Isso geralmente é usado para texto não estruturado, como transcrições, ensaios ou páginas da Web.
O operador de query $text
exige que você especifique o campo de pesquisa em um índice de texto na sua collection. Consulte abaixo exemplos de código para criar um índice de texto e utilizar o operador de query $text
.
Observação
O Atlas Search ajuda você a desenvolver recursos de pesquisa rápidos e baseados em relevância sobre os dados do MongoDB. Experimente hoje mesmo no MongoDB Atlas, nosso banco de dados totalmente gerenciado como serviço.
Exemplos
Os exemplos a seguir utilizam dados de amostra da coleção movies
no banco de dados sample_mflix
. Para habilitar pesquisas de texto no campo title
, crie um índice de texto usando o seguinte comando:
db.movies.createIndex({ title: "text" });
Nós usamos um único índice de texto de campo nos exemplos deste guia, mas você pode criar um índice de texto composto que amplia suas queries de texto para vários campos. O seguinte comando cria um índice de texto em dois campos na collection movies
:
db.movies.createIndex({ title: "text", plot: "text" });
Dica
Especificar pesos de campo em um índice de texto
Ao criar um índice de texto composto, você pode especificar uma opção de peso para priorizar determinados campos de texto em seu índice. Quando você executa uma pesquisa de texto, os pesos do campo influenciam como o MongoDB calcula a pontuação de pesquisa de texto para cada documento correspondente.
Para saber mais sobre como especificar pesos de campo ao criar um índice de texto, consulte a seção Índices de texto no guia Índices.
Você só pode criar um índice de texto por collection. Cada pesquisa de texto consulta todos os campos especificados nesse índice em busca de correspondências.
Para saber mais sobre índices de texto, consulte Índices de texto no manual do servidor.
Query por palavras
Este exemplo consulta filmes do Star Trek procurando títulos que contenham a palavra "trek". Se você quiser consultar usando várias palavras, separe-as com espaços para consultar documentos que correspondam a qualquer um dos termos de pesquisa (OR
lógico).
// Create a query that searches for the string "trek" const query = { $text: { $search: "trek" } }; // Return only the `title` of each matched document const projection = { _id: 0, title: 1, }; // Find documents based on our query and projection const cursor = movies.find(query).project(projection);
Esta operação retorna os seguintes documentos:
{ title: 'Trek Nation' } { title: 'Star Trek' } { title: 'Star Trek Into Darkness' } { title: 'Star Trek: Nemesis' } { title: 'Star Trek: Insurrection' } { title: 'Star Trek: Generations' } { title: 'Star Trek: First Contact' } { title: 'Star Trek: The Motion Picture' } { title: 'Star Trek VI: The Undiscovered Country' } { title: 'Star Trek V: The Final Frontier' } { title: 'Star Trek IV: The Voyage Home' } { title: 'Star Trek III: The Search for Spock' } { title: 'Star Trek II: The Wrath of Khan' }
Sucesso! A query encontrou todos os documentos na collection movies
com título incluindo a palavra "trek". Infelizmente, a pesquisa incluiu um item não intencional: "Trek Nation", que é um filme sobre Star Trek e não faz parte da série de filmes Star Trek. Para resolver isso, podemos consultar uma frase mais específica.
Query por frase
Para tornar sua query mais específica, tente usar a frase "star trek" em vez de apenas a palavra "trek". Para pesquisar por frase, coloque sua frase com as palavras entre aspas (\"<term>\"
):
// Create a query that searches for the phrase "star trek" const query = { $text: { $search: "\"star trek\"" } }; // Return only the `title` of each matched document const projection = { _id: 0, title: 1, }; // Find documents based on the query and projection const cursor = movies.find(query).project(projection);
A consulta pela frase "star trek"
, em vez de somente o termo "trek"
, corresponde aos seguintes documentos:
{ title: 'Star Trek' } { title: 'Star Trek Into Darkness' } { title: 'Star Trek: Nemesis' } { title: 'Star Trek: Insurrection' } { title: 'Star Trek: Generations' } { title: 'Star Trek: First Contact' } { title: 'Star Trek: The Motion Picture' } { title: 'Star Trek VI: The Undiscovered Country' } { title: 'Star Trek V: The Final Frontier' } { title: 'Star Trek IV: The Voyage Home' } { title: 'Star Trek III: The Search for Spock' } { title: 'Star Trek II: The Wrath of Khan' }
Esses resultados incluem todos os filmes no banco de dados que contêm a frase "star trek"
, que, nesse caso, resulta apenas em filmes fictícios Star Trek. Infelizmente, essa query retornou "Star Trek Into
Darkness"
, um filme que não fazia parte da série original de filmes. Para resolver esse problema, podemos omitir esse documento com uma negação.
Query com negações
Para usar um termo negado, coloque um sinal negativo, -
, na frente do termo que você deve omitir do conjunto de resultados. A operação de query emite quaisquer documentos que contenham este termo do resultado da pesquisa. Como esta query inclui dois termos distintos, separe-os com um espaço.
// Create a query that searches for the phrase "star trek" while omitting "into darkness" const query = { $text: { $search: "\"star trek\" -\"into darkness\"" } }; // Include only the `title` field of each matched document const projection = { _id: 0, title: 1, }; // Find documents based on the query and projection const cursor = movies.find(query).project(projection);
A query com o termo negado gera os seguintes documentos:
{ title: 'Star Trek' } { title: 'Star Trek: Nemesis' } { title: 'Star Trek: Insurrection' } { title: 'Star Trek: Generations' } { title: 'Star Trek: First Contact' } { title: 'Star Trek: The Motion Picture' } { title: 'Star Trek VI: The Undiscovered Country' } { title: 'Star Trek V: The Final Frontier' } { title: 'Star Trek IV: The Voyage Home' } { title: 'Star Trek III: The Search for Spock' } { title: 'Star Trek II: The Wrath of Khan' }
Observação
Sua operação de query pode retornar uma referência a um cursor que contém documentos correspondentes. Para saber como examinar os dados armazenados no cursor, consulte a página Fundamentos do cursor.
Classificar por relevância
Agora que o conjunto de resultados reflete os resultados desejados, você pode utilizar a pesquisa de texto textScore
, acessada utilizando o operador $meta na projeção de query, para ordenar os resultados por relevância:
// Create a query that searches for the phrase "star trek" while omitting "into darkness"r const query = { $text: { $search: "\"star trek\" -\"into darkness\"" } }; // Sort returned documents by descending text relevance score const sort = { score: { $meta: "textScore" } }; // Include only the `title` and `score` fields in each returned document const projection = { _id: 0, title: 1, score: { $meta: "textScore" }, }; // Find documents based on the query, sort, and projection const cursor = movies .find(query) .sort(sort) .project(projection);
A query desta forma retorna os seguintes documentos na seguinte ordem. Em geral, a relevância do texto aumenta à medida que uma cadeia de caracteres corresponde a mais termos e diminui à medida que a parte incomparável da cadeia de caracteres se alonga.
{ title: 'Star Trek', score: 1.5 } { title: 'Star Trek: Generations', score: 1.3333333333333333 } { title: 'Star Trek: Insurrection', score: 1.3333333333333333 } { title: 'Star Trek: Nemesis', score: 1.3333333333333333 } { title: 'Star Trek: The Motion Picture', score: 1.25 } { title: 'Star Trek: First Contact', score: 1.25 } { title: 'Star Trek II: The Wrath of Khan', score: 1.2 } { title: 'Star Trek III: The Search for Spock', score: 1.2 } { title: 'Star Trek IV: The Voyage Home', score: 1.2 } { title: 'Star Trek V: The Final Frontier', score: 1.2 } { title: 'Star Trek VI: The Undiscovered Country', score: 1.2 }
Para obter mais informações sobre o operador $text e suas opções, consulte a entrada manual.