// Engineering Log

Bases de datos: Parte 6 — MongoDB

Publicado el 21.09.2026

MongoDB — una base de datos orientada a documentos. En lugar de tablas con filas, almacena colecciones de documentos en formato BSON — la variante binaria de JSON con tipos adicionales (fechas, datos binarios, números decimales). Un documento puede contener objetos anidados y arreglos, y los documentos de una misma colección no tienen por qué tener el mismo conjunto de campos.

Licencia

MongoDB Community Server — las versiones publicadas desde el 16 de octubre de 2018 — se distribuyen bajo la licencia SSPL (Server Side Public License). Permite usar MongoDB gratuitamente en tus aplicaciones, incluidas las comerciales, pero exige divulgar el código fuente de toda la capa de servicio si ofreces MongoDB a terceros como un servicio. Open Source Initiative no reconoce la SSPL como licencia abierta, por lo que formalmente MongoDB no es software de código abierto. Los drivers para los lenguajes de programación se distribuyen bajo Apache 2.0.

Para una empresa que simplemente usa MongoDB como la base de su aplicación, la SSPL no impone restricciones. Si se necesita una licencia verdaderamente abierta, existe FerretDB — del que se habla más abajo.

Ramas soportadas en septiembre de 2026 — 7.0 y 8.0, la última estable — 8.3. Se recomienda instalar la versión estable más reciente: así lo recomienda la documentación.

Modelo documental

Ejemplo de documento de pedido:

json
{
  "_id": ObjectId("66f1c2a4e13b5a0012345678"),
  "number": "2026-0915",
  "customer": { "name": "ООО «Ромашка»", "inn": "7700000000" },
  "items": [
    { "sku": "A-100", "qty": 2, "price": NumberDecimal("1500.00") },
    { "sku": "B-200", "qty": 1, "price": NumberDecimal("4200.00") }
  ],
  "status": "paid",
  "created_at": ISODate("2026-09-15T10:12:00Z")
}

En una base relacional los mismos datos ocuparían tres tablas — pedidos, clientes, líneas — y para leer un pedido haría falta realizar joins. En MongoDB el pedido se lee entero con una sola consulta. Esta es la principal ventaja del modelo documental: los datos que la aplicación siempre lee y modifica juntos están almacenados juntos.

Una operación sobre un documento en MongoDB es atómica. Por eso, un esquema bien diseñado donde los datos relacionados están anidados en un único documento a menudo no requiere transacciones.

Cuándo está justificado el modelo documental

  • Los datos se representan naturalmente como objetos anidados: un pedido con sus líneas, un artículo con bloques de contenido, un perfil con configuraciones.
  • La estructura de los registros varía: un catálogo de productos donde un teléfono y un sofá tienen distintos conjuntos de características, registros de eventos de múltiples fuentes.
  • El esquema cambia frecuentemente en las etapas iniciales del producto: se puede empezar a escribir un nuevo campo sin migrar toda la colección.
  • Se necesita escalado horizontal: el sharding está integrado y distribuye la colección entre varios servidores.

Cuándo es mejor elegir una base relacional

  • Los datos están muy interconectados: contabilidad, donde facturas, contrapartes, almacenes y asientos se refieren entre sí. Las uniones en MongoDB se realizan mediante $lookup en el pipeline de agregación, y con muchas relaciones esto es más complicado y lento que un JOIN en PostgreSQL.
  • Importa la integridad estricta: claves foráneas, restricciones, comprobaciones a nivel de base son punto fuerte de las SGBD SQL.
  • Hay muchas consultas analíticas sobre campos arbitrarios: SQL es más cómodo para eso.
  • Solo necesitas campos JSON en una base normal: PostgreSQL con el tipo jsonb e índices GIN cubre muchas tareas por las que se elige MongoDB y mantiene todas las capacidades de SQL.

Un error frecuente es elegir MongoDB por la «falta de esquema». El esquema en la aplicación sigue existiendo, simplemente no está descrito en la base. Cuando el código cambia, en la colección quedan documentos en formato antiguo y la aplicación debe saber trabajar con ellos.

Validación del esquema

Para que la base no acepte documentos con estructura incorrecta, MongoDB tiene validación mediante JSON Schema:

javascript
db.createCollection("orders", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["number", "customer", "items", "status", "created_at"],
      properties: {
        number:     { bsonType: "string" },
        status:     { enum: ["new", "paid", "shipped", "cancelled"] },
        items:      { bsonType: "array", minItems: 1 },
        created_at: { bsonType: "date" }
      }
    }
  },
  validationLevel: "strict",   // verificar todas las inserciones y modificaciones
  validationAction: "error"    // rechazar documentos inválidos; "warn" — solo registrar en el log
})

Para una colección existente las reglas se añaden con el comando collMod. El modo validationLevel: "moderate" valida solo documentos nuevos y cambios de documentos que ya eran correctos — esto es útil al ordenar progresivamente datos antiguos.

Índices

Sin índice MongoDB examina toda la colección. Existen índices por un campo, compuestos, por elementos de arrays, de texto, geoespaciales, con tiempo de vida limitado (TTL — documentos eliminados automáticamente), únicos.

javascript
db.orders.createIndex({ status: 1, created_at: -1 })
db.sessions.createIndex({ created_at: 1 }, { expireAfterSeconds: 86400 })  // TTL: eliminar después de 24 horas

Para índices compuestos la documentación de MongoDB da la regla ESR: primero los campos por los que se busca coincidencia exacta (Equality), luego campos de ordenación (Sort), luego campos con rango (Range). Si una consulta usa un índice lo muestra explain("executionStats").

Conjunto de réplicas

En producción MongoDB no se ejecuta en un solo servidor, sino en un conjunto de réplicas (replica set): un nodo primario acepta escrituras y los secundarios reciben copia de los datos. Si el primario falla, los restantes eligen automáticamente uno nuevo. El mínimo recomendado son tres nodos.

Un conjunto de réplicas no solo sirve para tolerancia a fallos. Las transacciones multdocumento (desde la versión 4.0) y los flujos de cambios (change streams) funcionan únicamente en un conjunto de réplicas o en un clúster sharded — en un servidor único no están disponibles. Por eso, incluso para desarrollo a veces se inicia un conjunto de réplicas con un solo nodo.

Seguridad

Desde la versión 3.6 MongoDB por defecto acepta conexiones solo desde la dirección local, pero la verificación de contraseñas está desactivada por defecto. Las bases expuestas en Internet sin autorización son encontradas en masa por escáneres automáticos desde hace años: los datos se eliminan y dejan una nota exigiendo rescate.

Lo mínimo para una instalación de producción en mongod.conf:

yaml
net:
  bindIp: 127.0.0.1,10.0.0.5   # dirección local e interna, no pública
security:
  authorization: enabled

Antes de habilitar la autorización hay que crear un administrador, y para la aplicación un usuario separado con permisos solo en su base (rol readWrite). El puerto 27017 se bloquea con el firewall; como con Redis, al ejecutar en Docker no se publica en todas las interfaces.

Copias de seguridad

Para bases pequeñas y medianas sirve la utilidad mongodump del paquete MongoDB Database Tools (se instala por separado del servidor):

bash
mongodump --uri="mongodb://backup:ПАРОЛЬ@127.0.0.1:27017/?authSource=admin" \
  --oplog --gzip --archive=/backup/mongo-$(date +%F).archive.gz

mongorestore --gzip --archive=/backup/mongo-2026-09-21.archive.gz --oplogReplay

El parámetro --oplog solo funciona en un nodo de un conjunto de réplicas e incluye en la copia los cambios realizados durante la exportación — así se obtiene una copia consistente hasta el momento de finalización. Para un clúster sharded, antes de la exportación hay que detener el balanceador (sh.stopBalancer()) y las transacciones distribuidas. Para bases grandes mongodump es lento, y se copian mediante snapshots del sistema de archivos o herramientas especializadas.

FerretDB — alternativa de código abierto

FerretDB es un proyecto bajo licencia Apache 2.0 que acepta solicitudes por el protocolo de MongoDB y las ejecuta en PostgreSQL con la extensión DocumentDB. La aplicación se conecta a él con el driver normal de MongoDB. Los desarrolladores lo presentan como un reemplazo de MongoDB 5.0 y versiones posteriores en muchos casos, pero la compatibilidad no es completa: antes de migrar hay que verificar qué comandos y operadores usa tu aplicación. La ventaja es que los datos se almacenan en PostgreSQL, que ya se sabe administrar y respaldar.

Ventajas

  • El modelo documental coincide con la estructura de objetos en el código; los datos relacionados se leen con una sola consulta.
  • Esquema flexible que, si es necesario, se complementa con validación por JSON Schema.
  • Replicación integrada con conmutación automática.
  • Sharding para distribuir datos entre servidores.
  • Lenguaje de consultas y agregación desarrollado: filtrado, proyecciones, pipelines de agregación, búsqueda de texto y geobúsqueda.

Desventajas

  • La licencia SSPL no se considera abierta.
  • Las uniones de datos mediante $lookup son más complejas y lentas que los JOIN relacionales.
  • Las transacciones están disponibles solo en un conjunto de réplicas y cargan considerablemente la base; conviene usarlas solo como excepción.
  • El volumen de datos suele ser mayor que en una base relacional: los nombres de los campos se almacenan en cada documento. El tamaño de un documento está limitado a 16 MB.
  • Administración del clúster: un conjunto de réplicas y, aún más, un clúster sharded son más complejos de mantener que un servidor único de PostgreSQL.

MongoDB es adecuado para datos que encajan naturalmente en documentos y cambian de estructura, y para sistemas que necesitan escalado horizontal. Para sistemas de contabilidad con muchas relaciones, integridad estricta y análisis en SQL, es más fiable elegir PostgreSQL — posiblemente con campos jsonb para la parte de los datos que realmente necesita flexibilidad.

// Contact

¿Necesitas ayuda?

Escríbeme y te ayudaré a resolver el problema

Respondo en un día laborable (03:00-13:00 GMT)

Или оставьте заявку здесь:

Confirme que no es un bot.

Escribir y recibir una respuesta rápida