HOWTO · MongoDB

Consulta con longitud de cadena en MongoDB

Este tutorial discutirá cómo consultar con longitud de cadena en MongoDB.

En esta página

Para encontrar documentos de MongoDB cuyo campo de cadena tenga exactamente cinco puntos de código Unicode, usa $expr con $strLenCP en find(): db.mydata.find({ $expr: { $eq: [{ $strLenCP: "$Name" }, 5] } }). Esta forma abreviada supone que todos los documentos tienen un campo Name cuyo valor es una cadena. Más adelante se muestra una forma protegida que admite campos de tipos mixtos.

Consultar documentos por longitud de cadena en MongoDB

Usa una sola colección y nombres de campo coherentes al comparar distintos métodos. El siguiente ejemplo independiente en JavaScript define seis documentos de muestra y los filtra localmente según la longitud en puntos de código. No requiere conexión a una base de datos ni muestra una ejecución en el servidor de MongoDB.

El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.

const documents = [
  { _id: 1, Name: "hello" },
  { _id: 2, Name: "world" },
  { _id: 3, Name: "abcdefgh" },
  { _id: 4, Name: "ijklmnop" },
  { _id: 5, Name: "apple" },
  { _id: 6, Name: "grape" }
];
const matches = documents.filter(document => [...document.Name].length === 5);
console.log(JSON.stringify(matches, null, 2));
[
  {
    "_id": 1,
    "Name": "hello"
  },
  {
    "_id": 2,
    "Name": "world"
  },
  {
    "_id": 5,
    "Name": "apple"
  },
  {
    "_id": 6,
    "Name": "grape"
  }
]

Con estos datos, los documentos que coinciden con cinco puntos de código son 1, 2, 5 y 6: hello, world, apple y grape. Los documentos 3 y 4 tienen ocho puntos de código cada uno.

Los comandos de base de datos de este artículo son ejemplos de MongoDB shell que no se han ejecutado. Requieren una conexión a un servidor de MongoDB. Para crear la muestra en una colección nueva llamada mydata, usa db.mydata.insertMany([{ _id: 1, Name: "hello" }, { _id: 2, Name: "world" }, { _id: 3, Name: "abcdefgh" }, { _id: 4, Name: "ijklmnop" }, { _id: 5, Name: "apple" }, { _id: 6, Name: "grape" }]). Usa una colección de muestra aparte para evitar conflictos con valores _id existentes.

Usar $where para filtrar por longitud de cadena

El operador de consulta $where evalúa JavaScript en el servidor; su documentación describe las restricciones de implementación y el requisito de que las secuencias de comandos del servidor estén habilitadas. Cuando JavaScript del lado del servidor está disponible, puedes filtrar la muestra con db.mydata.find({ $where: function () { return typeof this.Name === "string" && this.Name.length === 5; } }).

La comprobación de tipo omite los valores ausentes, nulos y que no sean cadenas. Cambia === 5 por > 5 para buscar longitudes superiores a cinco. .length en JavaScript cuenta unidades de código UTF-16: un emoji fuera del plano multilingüe básico ocupa dos unidades. Por eso, este método coincide con los otros ejemplos para la muestra ASCII, pero no es un sustituto general del recuento de puntos de código. Usa $expr si quieres expresar la condición sin JavaScript del lado del servidor.

Usar $expr y $strLenCP en find()

El operador $expr permite que find() evalúe expresiones de agregación. $strLenCP cuenta puntos de código Unicode, mientras que $eq compara ese recuento con el valor objetivo. Sustituye $eq por $gt para buscar longitudes superiores a cinco, o por $gte para incluir cinco.

Como explica la documentación de $strLenCP, su entrada debe resolverse en una cadena; las entradas nulas o ausentes provocan un error. Usa una expresión condicional cuando Name pueda tener otro tipo:

db.mydata.find({ $expr: { $cond: [{ $eq: [{ $type: "$Name" }, "string"] }, { $eq: [{ $strLenCP: "$Name" }, 5] }, false] } })

Aquí $cond evalúa la comparación de longitud solo para las cadenas y devuelve false en los demás casos. Una cadena vacía tiene longitud cero; un campo ausente o nulo se omite, en lugar de tratarse como una cadena vacía. No conviene confiar en que una condición separada unida con $and se evalúe primero y proteja $strLenCP de entradas no adecuadas.

Los puntos de código no equivalen a bytes UTF-8 ni a caracteres visibles: una letra seguida de un acento combinante consta de dos puntos de código. Elige la regla de recuento que necesite tu aplicación.

Los enlaces a la documentación oficial de este artículo se incluyen como referencia; aquí no se han comprobado su disponibilidad ni sus contenidos actuales.

Para campos anidados, cambia la referencia de la expresión por una ruta con puntos, como "$parentField.childField", también en la comprobación de tipo. Combina condiciones completas con $and o $or cuando filtres varios campos.

Filtrar por longitud de cadena con una canalización de agregación

Usa una canalización de agregación cuando el filtrado forme parte de una transformación más amplia. Para la colección de muestra, esta etapa $match selecciona las dos cadenas de ocho puntos de código:

db.mydata.aggregate([{ $match: { $expr: { $eq: [{ $strLenCP: "$Name" }, 8] } } }])

Los documentos que coinciden son { _id: 3, Name: "abcdefgh" } y { _id: 4, Name: "ijklmnop" }. Este ejemplo supone que los valores son cadenas, como en la muestra. Para datos de tipos mixtos, sustituye el valor de $expr por la expresión $cond protegida de la sección anterior y establece el objetivo en ocho. Añade $project para cambiar la forma de los documentos coincidentes o $group para resumirlos.

Coincidir con una longitud de cadena fija mediante una expresión regular

Para las cadenas escalares de la muestra, que contienen letras ASCII, usa db.mydata.find({ Name: { $regex: "^.{5}$" } }). Los anclajes limitan la coincidencia y {5} repite el punto cinco veces, por lo que se seleccionan los documentos 1, 2, 5 y 6.

La documentación oficial de $regex explica las opciones de coincidencia y los anclajes pertinentes. Este patrón requiere matices para texto arbitrario: normalmente, el punto no incluye saltos de línea y $ puede coincidir antes de un salto de línea final. Un predicado de campo con una expresión regular también puede coincidir con un elemento de cadena dentro de una matriz. Prefiere la consulta protegida con $strLenCP cuando necesites una cadena escalar y un recuento explícito de puntos de código. Elige una expresión regular cuando la tarea dependa de patrones de caracteres y mide el rendimiento con tu propia carga de trabajo antes de tomar decisiones sobre eficiencia o índices.