MongoDB con PHP
Este articulo pretende explicar cómo usar MongoDB con el lenguaje de programación PHP y bajo Windows.
Lo primero que tienes que hacer es instalar el servidor de MongoDB si no lo tienes ya.
Instalación de la extensión
Si ya tienes MongoDB instalado, ahora, deberás instalar la extensión de MongoDB para PHP desde aquí eligiendo la versión adecuada para tu versión de PHP y arquitectura (x64 o x86).
Primero selecciona “DLL”:

Y después elije tu versión de PHP y arquitectura.
En mi caso es:

Configuración de la extensión
Ahora copia el archivo php_mongodb.dll a la carpeta de extensiones de PHP, que normalmente es la carpeta ext/ que se encuentra dentro de la carpeta de tu instalación de PHP.
En mi caso al usar laragon se encuentra en la siguiente ruta: C:\laragon\bin\php\php-8.2.10-Win32-vs16-x64\ext

Ahora edita tu archivo php.ini y añade la línea siguiente:
extension=mongodb

A continuación reinicia el servidor web para aplicar los cambios.
Por último, comprueba que la extensión se ha instalado correctamente creando un archivo php con el siguiente código:
<?php phpinfo(); ?>
Y busca «mongodb» para confirmar que la extensión está habilitada.

Instalar la biblioteca MongoDB PHP Driver
Ahora toca instalar la biblioteca desde Composer.
Seguramente que en este momento te preguntarás que, si ya tienes instalada la extensión, que necesidad hay de instalar “otra vez” MongoDB.
Tranquil@, como siempre te lo explico a continuación.
Extensión y biblioteca
Está claro que, en el primer paso, descargar e instalar el archivo .dll permitirá trabajar con MongoDB usando PHP, sin embargo, trabajaremos desde una capa de más bajo nivel y resultará más difícil, por eso, la recomendación es una vez instalada y habilitada la extensión, descargar MongoDB con Composer. Esto ofrece una API de alto nivel que hace que trabajar con MongoDB sea mucho más fácil y claro, permitiéndonos desarrollos mucho más avanzados y un mantenimiento más sencillo. Sobra decir que también nos ahorra mucho más tiempo.
Si te preguntas, ¿puedo instalar entonces solo MongoDB a través de Composer?
La respuesta es no.
La biblioteca MongoDB de Composer, usa internamente las funciones proporcionadas por la extensión. En otras palabras, el archivo php_mongodb.dll actúa como “un puente” entre PHP y el servidor MongoDB. La biblioteca de Composer solo es una capa adicional que utiliza ese puente para ofrecernos una API más sencilla.
Aclarado todo esto, continuemos con la instalación de la biblioteca.
Basta con abrir una terminal o línea de comandos y escribir (doy por hecho que ya tienes composer instalado):
composer require mongodb/mongodb
¡Y ya está! Ya podemos crear algún proyecto PHP usando la base de datos MongoDB 🥳
Como siempre, te intento mostrar algunos ejemplos.
Conexión
Lo primero es conectar a la base de datos. Recuerda que, en MongoDB la base de datos se creará automáticamente al insertar datos en ella.
Como ejemplo, vamos a crear una base de datos de empleados de una empresa:
<?php require 'vendor/autoload.php'; use MongoDB\Client; try { $client = new Client("mongodb://127.0.0.1:27017"); $db = $client->Empresa; // nombre de la base de datos $collection = $db->Empleados; // nombre de la colección (lo que equivaldria a la tabla) $result = $collection->insertMany([ ['nombre' => 'Ana', 'edad' => 25, 'cargo' => 'Junior Developer', 'num_empleado' => 1000], ['nombre' => 'Luis', 'edad' => 40, 'cargo' => 'Senior Developer', 'num_empleado' => 1001], ['nombre' => 'Marcos', 'edad' => 22, 'cargo' => 'Junior Developer', 'num_empleado' => 1002], ['nombre' => 'Maria', 'edad' => 20, 'cargo' => 'Diseñadora gráfica', 'num_empleado' => 1003] ]); echo "Se insertaron " . $result->getInsertedCount() . " documentos.\n"; } catch (Exception $e) { die("Error al conectar: " . $e->getMessage()); }
Si has leído el artículo anterior recuerda que para insertar un dato usamos insertOne() y para insertar varios insertMany() 😉
Unicidad
Es importante mencionar que, si ejecutamos el código anterior repetidas veces, se insertaran los mismos datos una y otra vez.
Para evitar la inserción de datos duplicados, necesitamos implementar un mecanismo que garantice la unicidad en la colección.
¿Cómo?
Mediante índices únicos.
Un índice único obliga a MongoDB a rechazar cualquier documento cuyo campo (o combinación de campos) ya exista en la colección.
Está claro que los nombres se pueden repetir, es decir, podemos tener en la empresa dos empleados llamados Luis e incluso que tengan el mismo cargo, sin embargo, no pueden tener el mismo número de empleado.
Así que modificamos el código anterior añadiendo un índice único:
<?php require 'vendor/autoload.php'; use MongoDB\Client; try { $client = new Client("mongodb://127.0.0.1:27017"); $db = $client->Empresa; // nombre de la base de datos $collection = $db->Empleados; // nombre de la colección (lo que equivaldria a la tabla) // Creamos un indice asegurando que no se repita el número de empleado $collection->createIndex(['num_empleado' => 1], ['unique' => true]); $result = $collection->insertMany([ ['nombre' => 'Ana', 'edad' => 25, 'cargo' => 'Junior Developer', 'num_empleado' => 1000], ['nombre' => 'Luis', 'edad' => 40, 'cargo' => 'Senior Developer', 'num_empleado' => 1001], ['nombre' => 'Marcos', 'edad' => 22, 'cargo' => 'Junior Developer', 'num_empleado' => 1002], ['nombre' => 'Maria', 'edad' => 20, 'cargo' => 'Diseñadora gráfica', 'num_empleado' => 1003] ]); echo "Se insertaron " . $result->getInsertedCount() . " documentos.\n"; } catch (Exception $e) { die("Error al insertar: " . $e->getMessage()); }
De esta manera nos aseguramos que los datos, en ese caso el número de empleado no se repita.
Si volvemos a ejecutar el código anterior, como se estará violando la regla de unicidad, MongoDB arrojará un error:
Error al conectar: E11000 duplicate key error collection: Empresa.Empleados index: num_empleado_1 dup key: { num_empleado: 1000 }
Seleccionar documentos
Lo que vendría a ser una consulta “SELECT” en SQL 😜
Para consultar todos los documentos:
<?php require 'vendor/autoload.php'; use MongoDB\Client; try { $client = new Client("mongodb://127.0.0.1:27017"); $db = $client->Empresa; // nombre de la base de datos $collection = $db->Empleados; // nombre de la colección (lo que equivaldria a la tabla) // Obtener todos los documentos: $documentos = $collection->find(); foreach ($documentos as $doc) { echo $doc['nombre'] . " de " . $doc['edad'] . " años, es el empleado Nº " . $doc['num_empleado'] . " y ocupa el cargo " . $doc['cargo'] . "<br>"; } } catch (Exception $e) { die("Error: " . $e->getMessage()); }
Y el resultado sería:
Ana de 25 años, es el empleado Nº 1000 y ocupa el cargo Junior Developer
Luis de 40 años, es el empleado Nº 1001 y ocupa el cargo Senior Developer
Marcos de 22 años, es el empleado Nº 1002 y ocupa el cargo Junior Developer
Maria de 20 años, es el empleado Nº 1003 y ocupa el cargo Diseñadora gráfica
Si queremos obtener solo un documento, es decir, para ser más concretos queremos consultar los datos del empleado número “1002”.
Pues por ejemplo modificamos el código así:
<?php require 'vendor/autoload.php'; use MongoDB\Client; try { $client = new Client("mongodb://127.0.0.1:27017"); $db = $client->Empresa; // nombre de la base de datos $collection = $db->Empleados; // nombre de la colección (lo que equivaldria a la tabla) // Buscar el empleado por num_empleado $doc = $collection->findOne(['num_empleado' => 1002]); echo $doc['nombre'] . " de " . $doc['edad'] . " años, es el empleado Nº " . $doc['num_empleado'] . " y ocupa el cargo " . $doc['cargo'] . "<br>"; } catch (Exception $e) { die("Error: " . $e->getMessage()); }
Vayamos un poco más allá. Ahora queremos consultar todos los empleados mayores de 20 años:
<?php require 'vendor/autoload.php'; use MongoDB\Client; try { $client = new Client("mongodb://127.0.0.1:27017"); $db = $client->Empresa; // nombre de la base de datos $collection = $db->Empleados; // nombre de la colección (lo que equivaldria a la tabla) $filtro = ['edad' => ['$gt' => 20]]; // Buscar empleados mayores a 20 años $documentos = $collection->find($filtro); foreach ($documentos as $doc) { echo $doc['nombre'] . " de " . $doc['edad'] . " años, es el empleado Nº " . $doc['num_empleado'] . " y ocupa el cargo " . $doc['cargo'] . "<br>"; } } catch (Exception $e) { die("Error: " . $e->getMessage()); }
El resultado:
Ana de 25 años, es el empleado Nº 1000 y ocupa el cargo Junior Developer
Luis de 40 años, es el empleado Nº 1001 y ocupa el cargo Senior Developer
Marcos de 22 años, es el empleado Nº 1002 y ocupa el cargo Junior Developer
Bastante claro, ¿no? 😉
Limitar resultados
En vez de mostrar todos los documentos quizás nos interese mostrar solo 2:
<?php require 'vendor/autoload.php'; use MongoDB\Client; try { $client = new Client("mongodb://127.0.0.1:27017"); $db = $client->Empresa; // nombre de la base de datos $collection = $db->Empleados; // nombre de la colección (lo que equivaldria a la tabla) $filtro = []; $opciones = ['limit' => 2]; // Solo obtener 2 documentos $documentos = $collection->find($filtro, $opciones); foreach ($documentos as $doc) { echo $doc['nombre'] . " de " . $doc['edad'] . " años, es el empleado Nº " . $doc['num_empleado'] . " y ocupa el cargo " . $doc['cargo'] . "<br>"; } } catch (Exception $e) { die("Error: " . $e->getMessage()); }
Está bien, pero ¿y si queremos ordenar los resultados?
Vamos a suponer que queremos mostrar solo 2 resultados pero que se muestren ordenados por edad, de mayor a menor:
<?php require 'vendor/autoload.php'; use MongoDB\Client; try { $client = new Client("mongodb://127.0.0.1:27017"); $db = $client->Empresa; // nombre de la base de datos $collection = $db->Empleados; // nombre de la colección (lo que equivaldria a la tabla) $filtro = []; $opciones = ['limit' => 2, 'sort' => ['edad' => -1]]; // Solo obtener 2 documentos $documentos = $collection->find($filtro, $opciones); foreach ($documentos as $doc) { echo $doc['nombre'] . " de " . $doc['edad'] . " años, es el empleado Nº " . $doc['num_empleado'] . " y ocupa el cargo " . $doc['cargo'] . "<br>"; } } catch (Exception $e) { die("Error: " . $e->getMessage()); }
¿Ves la diferencia?
Hago uso de la opción sort que permite especificar cómo se deben ordenar los resultados. Podemos ordenarlos en orden ascendente o descendente:
- Ascendente (1): Ordena de menor a mayor.
- Descendente (-1): Ordena de mayor a menor.
Contar documentos
Podemos contar el total de documentos que hay en una colección. Lo que equivaldría al total de datos que hay en una tabla.
<?php require 'vendor/autoload.php'; use MongoDB\Client; try { $client = new Client("mongodb://127.0.0.1:27017"); $db = $client->Empresa; // nombre de la base de datos $collection = $db->Empleados; // nombre de la colección (lo que equivaldria a la tabla) $total = $collection->countDocuments(); echo "Hay un total de $total documentos.\n"; } catch (Exception $e) { die("Error: " . $e->getMessage()); }
Actualización de documentos
Como siempre podemos actualizar un documento o varios. Todo ello con updateOne() y updateMany() respectivamente.
Ahora, resulta que Ana se ha quejado y su nombre completo es Ana Maria.
¡Pues vamos actualizarlo!
<?php require 'vendor/autoload.php'; use MongoDB\Client; try { $client = new Client("mongodb://127.0.0.1:27017"); $db = $client->Empresa; // nombre de la base de datos $collection = $db->Empleados; // nombre de la colección (lo que equivaldria a la tabla) $result = $collection->updateOne( ['nombre' => 'Ana'], // Filtro ['$set' => ['nombre' => 'Ana Maria']] // Datos a actualizar ); echo "Documentos modificados: " . $result->getModifiedCount() . "\n"; } catch (Exception $e) { die("Error al actualizar: " . $e->getMessage()); }

Vayamos un poco más allá (como siempre 😜) y esta vez queremos ascender a los «Junior Developer», es decir, resulta que son muy buenos y se merecen un cargo mejor.
¿Cómo lo haríamos?
<?php require 'vendor/autoload.php'; use MongoDB\Client; try { $client = new Client("mongodb://127.0.0.1:27017"); $db = $client->Empresa; // nombre de la base de datos $collection = $db->Empleados; // nombre de la colección (lo que equivaldria a la tabla) $result = $collection->updateMany( ['cargo' => 'Junior Developer'], // Filtro ['$set' => ['cargo' => 'Senior Developer']] // Actualizar cargo ); echo "Documentos modificados: " . $result->getModifiedCount() . "\n"; } catch (Exception $e) { die("Error al actualizar: " . $e->getMessage()); }

Eliminación de documentos
Como siempre tenemos la opción de eliminar uno o varios documentos con deleteOne() y deleteMany() respectivamente.
<?php require 'vendor/autoload.php'; use MongoDB\Client; try { $client = new Client("mongodb://127.0.0.1:27017"); $db = $client->Empresa; // nombre de la base de datos $collection = $db->Empleados; // nombre de la colección (lo que equivaldria a la tabla) $result = $collection->deleteOne(['num_empleado' => 1003]); echo "Empleados eliminados: " . $result->getDeletedCount() . "\n"; } catch (Exception $e) { die("Error al eliminar: " . $e->getMessage()); }
En el anterior ejemplo eliminamos al empleado cuyo número de empleado es 1003. El filtro es “num_empleado” pero como debes de saber ya, podemos usar cualquiera, es decir, podemos eliminar por nombre, cargo, edad, etc.
Una vez más avancemos un poco más.
Imagina que queremos eliminar los empleados menores de 25 años.
Pues por ejemplo el código sería así:
<?php require 'vendor/autoload.php'; use MongoDB\Client; try { $client = new Client("mongodb://127.0.0.1:27017"); $db = $client->Empresa; // nombre de la base de datos $collection = $db->Empleados; // nombre de la colección (lo que equivaldria a la tabla) $result = $collection->deleteMany(['edad' => ['$lt' => 25]]); // Menores de 25 echo "Empleados eliminados: " . $result->getDeletedCount() . "\n"; } catch (Exception $e) { die("Error al eliminar: " . $e->getMessage()); }
Como ves hemos aplicado como filtro el operador $lt.
Y el resultado:

También podríamos querer eliminar todos los documentos (empleados) de “golpe”:
<?php require 'vendor/autoload.php'; use MongoDB\Client; try { $client = new Client("mongodb://127.0.0.1:27017"); $db = $client->Empresa; // nombre de la base de datos $collection = $db->Empleados; // nombre de la colección (lo que equivaldria a la tabla) $result = $collection->deleteMany([]); echo "Se eliminaron todos los documentos: " . $result->getDeletedCount() . "\n"; } catch (Exception $e) { die("Error al eliminar: " . $e->getMessage()); }
Conclusión
Como has podido ver una base de datos NoSQL como es MongoDB varia no un poco, sino bastante en lo que respecta a una base de datos relacional.
Como ves no hay una consistencia clara ni una estructura fija de datos, lo cual, aunque como ejemplo haya usado una empresa de empleados, es evidente que en un caso real no sería recomendado usar este tipo de base de datos para tal fin.
Espero que te haya servido tanto este articulo como el anterior así como el de bases de datos NoSQL para un acercamiento a este tipo de bases de datos y al uso de MongoDB más concretamente.
Un saludito 😉
Sobre el autor
Este artículo está publicado bajo una licencia Creative Commons Atribución-CompartirIgual 4.0 Internacional . Puedes compartirlo y adaptarlo, incluso con fines comerciales, siempre que cites al autor y mantengas esta misma licencia.