Cómo usar consultas de texto

Usa las funciones de búsqueda de texto en Firestore con compatibilidad con MongoDB para buscar cadenas específicas dentro de una colección.

Antes de comenzar

Antes de comenzar a usar las búsquedas de texto, haz lo siguiente:

  1. Asegúrate de tener acceso a una base de datos existente compatible con las operaciones de MongoDB o crea una base de datos y conéctate a ella.

  2. Asegúrate de tener un índice de texto o crea uno.

Permisos de IAM

Para crear un índice en Firestore con compatibilidad con MongoDB, asegúrate de tener asignado alguno de los siguientes roles:

  • roles/datastore.owner
  • roles/datastore.indexAdmin
  • roles/editor
  • roles/owner

Para otorgar un rol, consulta Otorga un solo rol. Para obtener más información sobre los roles de Firestore y los permisos asociados, consulta Roles predefinidos.

Si definiste roles personalizados, asigna todos los permisos siguientes para crear índices:

  • datastore.indexes.create
  • datastore.indexes.delete
  • datastore.indexes.get
  • datastore.indexes.list
  • datastore.indexes.update

Ejecuta una búsqueda por texto

Las búsquedas de texto usan el operador $text dentro de un filtro. Especifica la cadena consultada en el argumento $search.

Ejecuta una consulta de texto general

Ejecuta la siguiente consulta para realizar una consulta general:

  # Find query
  db.cities.find({ $text: { $search: "french bread" } })

  # Aggregation query
  db.cities.aggregate([
    { $match: { $text: { $search: "french bread" } } }
  ]);

Si tu índice está particionado, puedes filtrar según la partición incluyendo la partición en un filtro de igualdad "y" dentro de tu consulta. Por ejemplo, si tuvieras una partición city, podrías filtrar una búsqueda de texto de la siguiente manera:

db.myCollection.find( { $and: [
  { $text: { $search: "french bread" } },
  { "city": "Paris" }
] } )

También puedes filtrar una agregación según una partición. Por ejemplo:

db.myCollection.aggregate([
 { $match: { $text: { $search: "french bread" } } },
 { "city": "Paris" }
] );

El valor de tu partición debe ser una cadena. Tu filtro de partición debe unirse a tu consulta con un "y".

Cómo establecer el lenguaje de la búsqueda

Puedes configurar el idioma de la consulta con el argumento $language. Por ejemplo:

  db.cities.find({ $text: { $search: "french bread", $language: "en"} })

Si no configuras el idioma de la búsqueda, esta usará el idioma del índice de texto.

Cómo buscar un término exacto

Para consultar un término exacto, configúralo como una secuencia de palabras entre comillas dobles. Por ejemplo:

  # Find query
  db.cities.find({ $text: { $search: "\"best french bread\"" } })

  # Aggregation query
  db.cities.aggregate([
    { $match: { $text: { $search: "\"best french bread\"" } } },
  ]);

Cómo consultar una combinación de términos

Para que tu búsqueda sea más precisa, especifica una cadena de términos. Por ejemplo, la siguiente consulta devuelve documentos que coinciden con la combinación best AND french AND ("bread" OR "is"):

  # Find query
  db.cities.find({ $text: { $search: "\"best\" \"french\" bread is" } })

  # Aggregation query
  db.cities.aggregate([
    { $match: { $text: { $search: "\"best\" \"french\" bread is" } } },
  ]);

Cómo excluir un término

Para excluir un término de una búsqueda, agrega un guion (-) antes del término:

  # Find query
  db.cities.find({ $text: { $search: "best bread -french"} })

  # Aggregation query
  db.cities.aggregate([
    { $match: { $text: { $search: "best bread -french" } } },
  ]);

Cómo calcular la puntuación de relevancia

Usa la expresión {$meta: "textScore"} para calcular la puntuación de relevancia de los documentos que coinciden con la búsqueda de texto. Para ordenar los resultados en orden descendente de la puntuación, usa $meta en una expresión de orden. Considera los siguientes ejemplos, en los que SCORE_FIELD es el nombre del campo que se usa para almacenar el valor de la puntuación:

  # Find query
  db.cities
    .find({ $text: { $search: "best french bread" } })
    .sort({ SCORE_FIELD: { $meta: "textScore" } })

  # Aggregation query
  db.cities.aggregate([
    { $match: { $text: { $search: "best french bread" } } },
    { $sort: { "SCORE_FIELD": { $meta: "textScore"} } },
  ]);

También puedes usar la puntuación de texto en las expresiones de proyección. Por ejemplo:

  # Find query
  db.cities
    .find({ $text: { $search: "best french bread" } })
    .project({ score: { $meta: "textScore" } })

  # Aggregation query
  db.cities.aggregate([
    { $match: { $text: { $search: "best french bread" } } },
    { $project: { "scoreField": { $meta: "textScore"} } },
  ]);

Expandir consulta

Para mejorar la relevancia de los resultados de la búsqueda, el operador $text aumenta la cadena de búsqueda según el idioma especificado para incluir coincidencias de sinónimos que tienen en cuenta el contexto, formas derivadas, términos corregidos ortográficamente, variaciones de diacríticos y mucho más.

Limitaciones

  • Los operadores $near y $text no se pueden usar en la misma consulta.
  • Se permite un solo operador $text por consulta de find o aggregation.
  • En las agregaciones, la etapa $match con $text debe ser la primera etapa de la canalización.
  • $text solo se puede anidar dentro de $and y $or.
  • Si $text está dentro de $or, las disyunciones que no son de búsqueda pueden usar índices ordenados existentes para optimizar la consulta. Si las otras disyunciones no están indexadas, la consulta se basará en un análisis de la colección.
  • $text no se puede usar con sugerencias de consultas.
  • Las búsquedas con consultas de texto no se pueden ordenar por $natural.