Overview
Las consultas de texto te permiten query campos de tipo string en tu colección para palabras o frases específicas. Puedes realizar una query de texto utilizando el operador $text, que realiza un OR lógico en cada término separado por un espacio en la string del query. También puede especificar más opciones para el operador a fin de gestionar la sensibilidad a mayúsculas y minúsculas, palabras vacías y reducción de palabras (como las formas plurales u otros tiempos verbales) para un lenguaje compatible. A menudo se utiliza para textos no estructurados tales como transcripciones, ensayos o páginas web.
El operador del query $text requiere que indiques el campo de query en un índice de texto de tu colección. Consulte los ejemplos a continuación para ver el código de muestra para crear un índice de texto y usar el operador del query $text.
Nota
MongoDB Search te ayuda a crear capacidades de búsqueda rápidas y basadas en relevancia sobre tus datos de MongoDB. Pruébalo hoy en MongoDB Atlas, nuestra base de datos totalmente gestionada como servicio.
Ejemplos
Los siguientes ejemplos utilizan datos de muestra de la colección movies en la base de datos sample_mflix. Para habilitar consultas de texto en el campo title, crea un índice de texto usando el siguiente comando:
await db.movies.createIndex({ title: "text" });
Utilizamos un índice de texto de un solo campo para los ejemplos de esta guía, pero puedes crear un índice de texto compuesto que amplíe tus consultas de texto a múltiples campos. El siguiente comando crea un índice de texto en dos campos de la colección movies:
await db.movies.createIndex({ title: "text", plot: "text" });
Tip
Especificar pesos de campo en un índice de texto
Al crear un índice de texto compuesto, puedes especificar una opción de peso para priorizar ciertos campos de texto en tu índice. Cuando ejecutes una query de texto, los pesos de los campos influyen en cómo MongoDB calcula la puntuación de query de texto para cada documento coincidente.
Para obtener más información sobre cómo especificar los pesos de campo al crear un índice de texto, consulte la sección Índices de texto en la guía de Índices.
Solo puedes crear un índice de texto por colección. Cada query de texto busca coincidencias en todos los campos especificados en ese índice.
Para obtener más información sobre los índices de texto, consulta Índices de Texto en el Manual del Servidor.
query para palabras
Este ejemplo consulta películas de Star Trek buscando títulos que contengan la palabra "trek". Si deseas realizar una query utilizando varias palabras, separa las palabras con espacios para buscar documentos que coincidan con alguno de los términos de búsqueda (condición lógica OR).
// 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 operación devuelve los siguientes 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' }
éxito! La query encontró todos los documentos en la colección movies con un título que incluía la palabra "trek". Desafortunadamente, la búsqueda incluyó un elemento no intencionado: "Trek Nation", que es una película sobre Star Trek y no forma parte de la serie de películas de Star Trek. Para resolver esto, podemos hacer una búsqueda con una frase más específica.
Query por frase
Para que tu consulta sea más específica, intenta usar la frase "star trek" en lugar de solo la palabra "trek". Para buscar por frase, encierra tu frase de varias palabras entre comillas escapadas (\"<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);
La consulta por la frase "star trek" en lugar del término "trek" coincide con los siguientes 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' }
Estos resultados incluyen todas las películas de la base de datos que contienen la frase "star trek", que en este caso se traduce sólo en películas de Star Trek de ficción. Desafortunadamente, esta consulta devolvió "Star Trek Into Darkness", una película que no formaba parte de la serie original de películas. Para resolver este problema, podemos omitir ese documento con una negación.
Query con negaciones
Para usar un término negado, coloque un signo negativo, -, delante del término que desea omitir del conjunto de resultados. La operación de query omite cualquier documento que contenga este término de los resultados de búsqueda. Dado que esta query incluye dos términos distintos, sepáralos con un espacio.
// 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);
La consulta con el término negado produce los siguientes 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' }
Nota
La operación de la query puede devolver una referencia a un cursor que contiene documentos coincidentes. Para aprender cómo examinar los datos almacenados en el cursor, consulta la página Acceso a los datos desde un cursor.
Ordenar por Relevancia
Ahora que el conjunto de resultados refleja los resultados deseados, puedes utilizar la query de texto textScore, accedida mediante el operador $meta en la proyección de la query, para ordenar los resultados por relevancia:
// 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);
Consultar de esta manera devuelve los siguientes documentos en el siguiente orden. En general, la relevancia del texto aumenta a medida que una string coincide con más términos y disminuye a medida que la parte no coincidente de la string se alarga.
{ 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 obtener más información sobre el operador $text y sus opciones, consulta la página del manual.