MongoDB
Introducción
MongoDB es una base de datos NoSQL orientada a documentos. En lugar de tablas y filas, los datos se guardan en documentos con un formato similar a JSON, lo que permite una gran flexibilidad en el modelo de datos.
Netuno ofrece el recurso _mongo para la integración con MongoDB, con una abstracción low-code sobre el cliente oficial de MongoDB para Java, disponible para los distintos lenguajes de programación soportados por Netuno: JavaScript, Python, Ruby, Kotlin y Groovy.
Antes de continuar, se recomienda saber cómo crear servicios en Netuno; consulte el tutorial REST - Servicios Web.
Un ejemplo de implementación de las operaciones presentadas aquí está disponible en el servicio de ejemplo mongo.js, que se encuentra en:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
apps/demo/server/services/samples/javascript/mongo.js
apps/demo/server/services/samples/javascript/mongo.ts
apps/demo/server/services/samples/javascript/mongo.py
apps/demo/server/services/samples/javascript/mongo.rb
apps/demo/server/services/samples/javascript/mongo.kts
apps/demo/server/services/samples/javascript/mongo.groovy
Instalación de MongoDB
Con Docker
Suponiendo que tenga Docker instalado, basta con descargar la imagen de MongoDB e iniciar un nuevo contenedor:
docker pull mongo
docker run -d --name mongo -p 27017:27017 mongo
De esta forma, MongoDB queda accesible en localhost:27017 sin autenticación.
Para crear el usuario de la base de datos según la configuración de la aplicación, ejecute:
docker exec -it mongo mongosh productos_db --eval 'db.createUser({ user: "usuario_productos", pwd: "12345678", roles: [{ role: "readWrite", db: "productos_db" }] })'
Con Ubuntu
MongoDB no está incluido en los repositorios oficiales de Ubuntu, por lo que es necesario añadir el repositorio oficial antes de la instalación:
sudo apt-get install gnupg curl
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor
echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] http://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
sudo apt-get update
sudo apt-get install -y mongodb-org
Una vez instalado, puede iniciar el servicio con:
sudo systemctl start mongod
Con Windows
Ejecute el instalador descargado y, en el paso Service Configuration, active Install MongoD as a Service para que MongoDB arranque automáticamente. MongoDB queda accesible en localhost:27017 sin autenticación.
Consulte la documentación oficial de MongoDB para otras distribuciones y versiones.
Configuración de la Aplicación
La configuración de las conexiones de MongoDB se realiza en el archivo de configuración de la aplicación, según el entorno:
config/_development.json
Vea más sobre los archivos de configuración de la aplicación.
Dentro del archivo de configuración, añada el bloque mongo, donde cada clave identifica una conexión:
{
...
"mongo": {
"tienda": "mongodb://usuario_tienda:12345678@localhost/tienda_db",
"productos": {
"username": "usuario_productos",
"password": "12345678",
"host": "127.0.0.1",
"port": "27017",
"database": "productos_db"
}
},
...
}
Una conexión se puede definir de dos formas:
- Como URL de conexión — el valor es simplemente una cadena, por ejemplo
"mongodb://usuario_tienda:12345678@localhost/tienda_db". - Como objeto de configuración — con los campos:
url— si se define, se utiliza directamente como URL de conexión, ignorando los demás campos.protocol— el protocolo de la conexión, por defectomongodb.usernameypassword— las credenciales de acceso.host— la dirección del servidor, por defectolocalhost.port— el puerto de la conexión, por defecto27017.database— el nombre de la base de datos, por defecto el nombre de la clave de la conexión.params— parámetros adicionales de la conexión añadidos a la URL, por ejemplo{ "authSource": "admin" }. Solo se aplican cuando la URL se construye a partir de los campos del objeto.
La conexión no tiene que ser la base de datos principal de la aplicación. A diferencia de la configuración
db, el bloquemongoes independiente y permite varias conexiones simultáneas.
Inicializar la Conexión
El primer paso es inicializar el cliente de MongoDB con el recurso _mongo.init(...), pasando el nombre de la clave de configuración o directamente una URL de conexión:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const mongo = _mongo.init("productos")
const mongo = _mongo.init("productos")
mongo = _mongo.init("productos")
mongo = _mongo.init("productos")
val mongo = _mongo.init("productos")
def mongo = _mongo.init("productos")
También puede inicializar la conexión directamente con una URL:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const mongo = _mongo.init("mongodb://localhost:27017/productos_db")
const mongo = _mongo.init("mongodb://localhost:27017/productos_db")
mongo = _mongo.init("mongodb://localhost:27017/productos_db")
mongo = _mongo.init("mongodb://localhost:27017/productos_db")
val mongo = _mongo.init("mongodb://localhost:27017/productos_db")
def mongo = _mongo.init("mongodb://localhost:27017/productos_db")
Al llamar a
_mongo.init()sin argumentos se utiliza la clave de configuracióndefault. Se recomienda pasar siempre el nombre de la clave o la URL, para que quede explícita la conexión utilizada.
Base de Datos y Colecciones
Con el cliente inicializado, obtenga la instancia de la base de datos con database("nombre"). A continuación puede crear colecciones y acceder a una colección existente:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const db = mongo.database("productos_db")
db.createCollection("producto")
const coleccion = db.collection("producto")
const db = mongo.database("productos_db")
db.createCollection("producto")
const coleccion = db.collection("producto")
db = mongo.database("productos_db")
db.createCollection("producto")
coleccion = db.collection("producto")
db = mongo.database("productos_db")
db.createCollection("producto")
coleccion = db.collection("producto")
val db = mongo.database("productos_db")
db.createCollection("producto")
val coleccion = db.collection("producto")
def db = mongo.database("productos_db")
db.createCollection("producto")
def coleccion = db.collection("producto")
Puede probar la conexión con la base de datos con ping(), y listar todas las colecciones existentes con collectionNames():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
db.ping()
const nombres = db.collectionNames()
db.ping()
const nombres = db.collectionNames()
db.ping()
nombres = db.collectionNames()
db.ping()
nombres = db.collectionNames()
db.ping()
val nombres = db.collectionNames()
db.ping()
def nombres = db.collectionNames()
Puede renombrar una colección con renameCollection(), pasando el nombre completo con la base de datos, o el nombre de la base de datos y el nuevo nombre de la colección por separado:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
coleccion.renameCollection("productos_db.producto_archivo")
coleccion.renameCollection("archivo_db", "producto_archivo")
coleccion.renameCollection("productos_db.producto_archivo")
coleccion.renameCollection("archivo_db", "producto_archivo")
coleccion.renameCollection("productos_db.producto_archivo")
coleccion.renameCollection("archivo_db", "producto_archivo")
coleccion.renameCollection("productos_db.producto_archivo")
coleccion.renameCollection("archivo_db", "producto_archivo")
coleccion.renameCollection("productos_db.producto_archivo")
coleccion.renameCollection("archivo_db", "producto_archivo")
coleccion.renameCollection("productos_db.producto_archivo")
coleccion.renameCollection("archivo_db", "producto_archivo")
Para eliminar una colección y todos sus documentos, utilice drop():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
coleccion.drop()
coleccion.drop()
coleccion.drop()
coleccion.drop()
coleccion.drop()
coleccion.drop()
Insertar Documentos
Los datos se representan con el recurso _val, mediante _val.map() para documentos y _val.list() para listas de valores.
Insertar un único documento
Con insertOne() inserta un documento y obtiene el ID generado:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const id = coleccion.insertOne(
_val.map()
.set("nombre", "Portátil")
.set("cantidad", 22)
.set("precio", 100)
.set("categoria", "ordenadores")
)
const id = coleccion.insertOne(
_val.map()
.set("nombre", "Portátil")
.set("cantidad", 22)
.set("precio", 100)
.set("categoria", "ordenadores")
)
id = coleccion.insertOne(
_val.map()
.set("nombre", "Portátil")
.set("cantidad", 22)
.set("precio", 100)
.set("categoria", "ordenadores")
)
id = coleccion.insertOne(
_val.map()
.set("nombre", "Portátil")
.set("cantidad", 22)
.set("precio", 100)
.set("categoria", "ordenadores")
)
val id = coleccion.insertOne(
_val.map()
.set("nombre", "Portátil")
.set("cantidad", 22)
.set("precio", 100)
.set("categoria", "ordenadores")
)
def id = coleccion.insertOne(
_val.map()
.set("nombre", "Portátil")
.set("cantidad", 22)
.set("precio", 100)
.set("categoria", "ordenadores")
)
Los documentos pueden contener estructuras anidadas, como listas y otros documentos:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
coleccion.insertOne(
_val.map()
.set("nombre", "Tableta")
.set("etiquetas",
_val.list()
.add("promo")
.add("nuevo")
)
.set("detalles",
_val.map()
.set("color", "azul")
.set("stock", 10)
)
)
coleccion.insertOne(
_val.map()
.set("nombre", "Tableta")
.set("etiquetas",
_val.list()
.add("promo")
.add("nuevo")
)
.set("detalles",
_val.map()
.set("color", "azul")
.set("stock", 10)
)
)
coleccion.insertOne(
_val.map()
.set("nombre", "Tableta")
.set("etiquetas",
_val.list()
.add("promo")
.add("nuevo")
)
.set("detalles",
_val.map()
.set("color", "azul")
.set("stock", 10)
)
)
coleccion.insertOne(
_val.map()
.set("nombre", "Tableta")
.set("etiquetas",
_val.list()
.add("promo")
.add("nuevo")
)
.set("detalles",
_val.map()
.set("color", "azul")
.set("stock", 10)
)
)
coleccion.insertOne(
_val.map()
.set("nombre", "Tableta")
.set("etiquetas",
_val.list()
.add("promo")
.add("nuevo")
)
.set("detalles",
_val.map()
.set("color", "azul")
.set("stock", 10)
)
)
coleccion.insertOne(
_val.map()
.set("nombre", "Tableta")
.set("etiquetas",
_val.list()
.add("promo")
.add("nuevo")
)
.set("detalles",
_val.map()
.set("color", "azul")
.set("stock", 10)
)
)
Insertar múltiples documentos
Con insertMany() inserta varios documentos de una sola vez, recibiendo la lista de IDs generados:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const ids = coleccion.insertMany(
_val.list()
.add(
_val.map()
.set("nombre", "Smartphone")
.set("cantidad", 18)
)
.add(
_val.map()
.set("nombre", "Monitor")
.set("cantidad", 8)
)
)
const ids = coleccion.insertMany(
_val.list()
.add(
_val.map()
.set("nombre", "Smartphone")
.set("cantidad", 18)
)
.add(
_val.map()
.set("nombre", "Monitor")
.set("cantidad", 8)
)
)
ids = coleccion.insertMany(
_val.list()
.add(
_val.map()
.set("nombre", "Smartphone")
.set("cantidad", 18)
)
.add(
_val.map()
.set("nombre", "Monitor")
.set("cantidad", 8)
)
)
ids = coleccion.insertMany(
_val.list()
.add(
_val.map()
.set("nombre", "Smartphone")
.set("cantidad", 18)
)
.add(
_val.map()
.set("nombre", "Monitor")
.set("cantidad", 8)
)
)
val ids = coleccion.insertMany(
_val.list()
.add(
_val.map()
.set("nombre", "Smartphone")
.set("cantidad", 18)
)
.add(
_val.map()
.set("nombre", "Monitor")
.set("cantidad", 8)
)
)
def ids = coleccion.insertMany(
_val.list()
.add(
_val.map()
.set("nombre", "Smartphone")
.set("cantidad", 18)
)
.add(
_val.map()
.set("nombre", "Monitor")
.set("cantidad", 8)
)
)
Consultar Documentos
El método find() devuelve un MongoFindIterable, a partir del cual se obtienen los documentos con all() (todos) o first() (el primero, o null si no hay ninguno).
Para obtener todos los documentos de la colección:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentos = coleccion.find().all()
const documentos = coleccion.find().all()
documentos = coleccion.find().all()
documentos = coleccion.find().all()
val documentos = coleccion.find().all()
def documentos = coleccion.find().all()
Para consultar con un filtro, utilice la factoría _mongo.filters():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentos = coleccion.find(
_mongo.filters().eq("nombre", "Portátil")
).all()
const documentos = coleccion.find(
_mongo.filters().eq("nombre", "Portátil")
).all()
documentos = coleccion.find(
_mongo.filters().eq("nombre", "Portátil")
).all()
documentos = coleccion.find(
_mongo.filters().eq("nombre", "Portátil")
).all()
val documentos = coleccion.find(
_mongo.filters().eq("nombre", "Portátil")
).all()
def documentos = coleccion.find(
_mongo.filters().eq("nombre", "Portátil")
).all()
Filtros
La factoría _mongo.filters() ofrece los principales operadores de consulta de MongoDB:
| Operador | Descripción |
|---|---|
eq("campo", valor) | Igual al valor. |
ne("campo", valor) | Distinto del valor. |
gt("campo", valor) | Mayor que el valor. |
gte("campo", valor) | Mayor o igual que el valor. |
lt("campo", valor) | Menor que el valor. |
lte("campo", valor) | Menor o igual que el valor. |
in("campo", valor1, valor2, ...) | Igual a cualquiera de los valores. |
nin("campo", valor1, valor2, ...) | Distinto de todos los valores. |
and(filtro1, filtro2, ...) | Coincide con todos los filtros. |
or(filtro1, filtro2, ...) | Coincide con al menos uno de los filtros. |
not(filtro) | No coincide con el filtro. |
regex("campo", "patrón") | Coincide con la expresión regular. |
exists("campo") | El campo existe en el documento. |
text("búsqueda") | Búsqueda de texto. |
type("campo", "tipo") | El campo es del tipo especificado. |
mod("campo", divisor, resto) | El resto de la división del campo por el divisor es igual al valor. |
where("expresión") | Coincide con los documentos que satisfacen una expresión JavaScript, por ejemplo "this.precio > 100". |
size("campo", n) | El campo de matriz tiene exactamente n elementos. |
Por ejemplo, para obtener los productos con precio superior a 50 y cantidad inferior a 30:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentos = coleccion.find(
_mongo.filters().and(
_mongo.filters().gt("precio", 50),
_mongo.filters().lt("cantidad", 30)
)
).all()
const documentos = coleccion.find(
_mongo.filters().and(
_mongo.filters().gt("precio", 50),
_mongo.filters().lt("cantidad", 30)
)
).all()
documentos = coleccion.find(
_mongo.filters().and(
_mongo.filters().gt("precio", 50),
_mongo.filters().lt("cantidad", 30)
)
).all()
documentos = coleccion.find(
_mongo.filters().and(
_mongo.filters().gt("precio", 50),
_mongo.filters().lt("cantidad", 30)
)
).all()
val documentos = coleccion.find(
_mongo.filters().and(
_mongo.filters().gt("precio", 50),
_mongo.filters().lt("cantidad", 30)
)
).all()
def documentos = coleccion.find(
_mongo.filters().and(
_mongo.filters().gt("precio", 50),
_mongo.filters().lt("cantidad", 30)
)
).all()
O para obtener los productos cuyo nombre coincide con una expresión regular:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentos = coleccion.find(
_mongo.filters().regex("nombre", "^[PS]")
).all()
const documentos = coleccion.find(
_mongo.filters().regex("nombre", "^[PS]")
).all()
documentos = coleccion.find(
_mongo.filters().regex("nombre", "^[PS]")
).all()
documentos = coleccion.find(
_mongo.filters().regex("nombre", "^[PS]")
).all()
val documentos = coleccion.find(
_mongo.filters().regex("nombre", "^[PS]")
).all()
def documentos = coleccion.find(
_mongo.filters().regex("nombre", "^[PS]")
).all()
Recorrer los Resultados
Con el resultado de la consulta puede recorrer todos los documentos encontrados:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
for (const documento of coleccion.find().all()) {
_out.println(documento.getString("nombre"))
}
for (const documento of coleccion.find().all()) {
_out.println(documento.getString("nombre"))
}
for documento in coleccion.find().all():
_out.println(documento.getString("nombre"))
coleccion.find().all().each do |documento|
_out.println(documento.getString("nombre"))
end
for (documento in coleccion.find().all()) {
_out.println(documento.getString("nombre"))
}
for (documento in coleccion.find().all()) {
_out.println(documento.getString("nombre"))
}
También puede recorrer los resultados con forEach() pasando una función:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
coleccion.find().forEach((documento) =>
_out.println(documento.getString("nombre"))
)
coleccion.find().forEach((documento) =>
_out.println(documento.getString("nombre"))
)
coleccion.find().forEach(
lambda documento: _out.println(documento.getString("nombre"))
)
coleccion.find().forEach do |documento|
_out.println(documento.getString("nombre"))
end
coleccion.find().forEach { documento ->
_out.println(documento.getString("nombre"))
}
coleccion.find().forEach { documento ->
_out.println(documento.getString("nombre"))
}
Ordenación
Con la factoría _mongo.sorts() se define el orden de los resultados, de forma ascendente o descendente:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentos = coleccion.find().sort(
_mongo.sorts().descending("precio")
).all()
const documentos = coleccion.find().sort(
_mongo.sorts().descending("precio")
).all()
documentos = coleccion.find().sort(
_mongo.sorts().descending("precio")
).all()
documentos = coleccion.find().sort(
_mongo.sorts().descending("precio")
).all()
val documentos = coleccion.find().sort(
_mongo.sorts().descending("precio")
).all()
def documentos = coleccion.find().sort(
_mongo.sorts().descending("precio")
).all()
Para ordenar por varios campos, utilice orderBy():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentos = coleccion.find().sort(
_mongo.sorts().orderBy(
_mongo.sorts().descending("precio"),
_mongo.sorts().ascending("cantidad")
)
).all()
const documentos = coleccion.find().sort(
_mongo.sorts().orderBy(
_mongo.sorts().descending("precio"),
_mongo.sorts().ascending("cantidad")
)
).all()
documentos = coleccion.find().sort(
_mongo.sorts().orderBy(
_mongo.sorts().descending("precio"),
_mongo.sorts().ascending("cantidad")
)
).all()
documentos = coleccion.find().sort(
_mongo.sorts().orderBy(
_mongo.sorts().descending("precio"),
_mongo.sorts().ascending("cantidad")
)
).all()
val documentos = coleccion.find().sort(
_mongo.sorts().orderBy(
_mongo.sorts().descending("precio"),
_mongo.sorts().ascending("cantidad")
)
).all()
def documentos = coleccion.find().sort(
_mongo.sorts().orderBy(
_mongo.sorts().descending("precio"),
_mongo.sorts().ascending("cantidad")
)
).all()
Proyección de Campos
Con la factoría _mongo.projections() se limitan los campos devueltos en los documentos:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentos = coleccion.find().projection(
_mongo.projections().include("nombre", "cantidad")
).all()
const documentos = coleccion.find().projection(
_mongo.projections().include("nombre", "cantidad")
).all()
documentos = coleccion.find().projection(
_mongo.projections().include("nombre", "cantidad")
).all()
documentos = coleccion.find().projection(
_mongo.projections().include("nombre", "cantidad")
).all()
val documentos = coleccion.find().projection(
_mongo.projections().include("nombre", "cantidad")
).all()
def documentos = coleccion.find().projection(
_mongo.projections().include("nombre", "cantidad")
).all()
Para combinar varias proyecciones:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentos = coleccion.find().projection(
_mongo.projections().fields(
_mongo.projections().include("nombre", "cantidad"),
_mongo.projections().excludeId()
)
).all()
const documentos = coleccion.find().projection(
_mongo.projections().fields(
_mongo.projections().include("nombre", "cantidad"),
_mongo.projections().excludeId()
)
).all()
documentos = coleccion.find().projection(
_mongo.projections().fields(
_mongo.projections().include("nombre", "cantidad"),
_mongo.projections().excludeId()
)
).all()
documentos = coleccion.find().projection(
_mongo.projections().fields(
_mongo.projections().include("nombre", "cantidad"),
_mongo.projections().excludeId()
)
).all()
val documentos = coleccion.find().projection(
_mongo.projections().fields(
_mongo.projections().include("nombre", "cantidad"),
_mongo.projections().excludeId()
)
).all()
def documentos = coleccion.find().projection(
_mongo.projections().fields(
_mongo.projections().include("nombre", "cantidad"),
_mongo.projections().excludeId()
)
).all()
Los tipos de proyección disponibles son los siguientes:
| Proyección | Descripción |
|---|---|
include("campo", ...) | Incluye únicamente los campos especificados. |
exclude("campo", ...) | Excluye los campos especificados. |
excludeId() | Excluye el campo _id. |
fields(proyección1, ...) | Combina proyecciones. |
slice("campo", n) | Incluye únicamente los primeros n elementos del campo de matriz. |
slice("campo", salto, n) | Incluye n elementos del campo de matriz, a partir de después de los primeros salto elementos. |
elemMatch("campo") | Incluye únicamente el primer elemento del campo de matriz. |
elemMatch("campo", filtro) | Incluye únicamente el primer elemento de la matriz que coincide con el filtro. |
computed("campo", expresión) | Añade un campo calculado a partir de una expresión de agregación. |
Límites y Saltos
Con limit() y skip() se controla la cantidad de resultados devueltos:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentos = coleccion.find()
.skip(1)
.limit(2)
.all()
const documentos = coleccion.find()
.skip(1)
.limit(2)
.all()
documentos = coleccion.find()
.skip(1)
.limit(2)
.all()
documentos = coleccion.find()
.skip(1)
.limit(2)
.all()
val documentos = coleccion.find()
.skip(1)
.limit(2)
.all()
def documentos = coleccion.find()
.skip(1)
.limit(2)
.all()
Actualizar Documentos
Con la factoría _mongo.updates() se definen los cambios a aplicar, y con updateOne() o updateMany() se aplican los cambios en los documentos que coinciden con el filtro:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
coleccion.updateOne(
_mongo.filters().eq("nombre", "Portátil"),
_mongo.updates().set("cantidad", 42)
)
coleccion.updateMany(
_mongo.filters().eq("categoria", "ordenadores"),
_mongo.updates().set("categoria", "destacado")
)
coleccion.updateOne(
_mongo.filters().eq("nombre", "Portátil"),
_mongo.updates().set("cantidad", 42)
)
coleccion.updateMany(
_mongo.filters().eq("categoria", "ordenadores"),
_mongo.updates().set("categoria", "destacado")
)
coleccion.updateOne(
_mongo.filters().eq("nombre", "Portátil"),
_mongo.updates().set("cantidad", 42)
)
coleccion.updateMany(
_mongo.filters().eq("categoria", "ordenadores"),
_mongo.updates().set("categoria", "destacado")
)
coleccion.updateOne(
_mongo.filters().eq("nombre", "Portátil"),
_mongo.updates().set("cantidad", 42)
)
coleccion.updateMany(
_mongo.filters().eq("categoria", "ordenadores"),
_mongo.updates().set("categoria", "destacado")
)
coleccion.updateOne(
_mongo.filters().eq("nombre", "Portátil"),
_mongo.updates().set("cantidad", 42)
)
coleccion.updateMany(
_mongo.filters().eq("categoria", "ordenadores"),
_mongo.updates().set("categoria", "destacado")
)
coleccion.updateOne(
_mongo.filters().eq("nombre", "Portátil"),
_mongo.updates().set("cantidad", 42)
)
coleccion.updateMany(
_mongo.filters().eq("categoria", "ordenadores"),
_mongo.updates().set("categoria", "destacado")
)
La factoría _mongo.updates() ofrece los operadores de actualización:
| Operador | Descripción |
|---|---|
set("campo", valor) | Define el valor de un campo. |
unset("campo") | Elimina un campo del documento. |
rename("campo", "nuevoNombre") | Renombra un campo. |
push("campo", valor) | Añade un valor a un array. |
combine(actualización1, actualización2, ...) | Combina varias actualizaciones en una sola. |
Para aplicar varios cambios de una sola vez, utilice combine():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const combinada = _mongo.updates().combine(
_mongo.updates().set("cantidad", 42),
_mongo.updates().rename("otro", "mas")
)
coleccion.updateOne(
_mongo.filters().eq("nombre", "Portátil"),
combinada
)
const combinada = _mongo.updates().combine(
_mongo.updates().set("cantidad", 42),
_mongo.updates().rename("otro", "mas")
)
coleccion.updateOne(
_mongo.filters().eq("nombre", "Portátil"),
combinada
)
combinada = _mongo.updates().combine(
_mongo.updates().set("cantidad", 42),
_mongo.updates().rename("otro", "mas")
)
coleccion.updateOne(
_mongo.filters().eq("nombre", "Portátil"),
combinada
)
combinada = _mongo.updates().combine(
_mongo.updates().set("cantidad", 42),
_mongo.updates().rename("otro", "mas")
)
coleccion.updateOne(
_mongo.filters().eq("nombre", "Portátil"),
combinada
)
val combinada = _mongo.updates().combine(
_mongo.updates().set("cantidad", 42),
_mongo.updates().rename("otro", "mas")
)
coleccion.updateOne(
_mongo.filters().eq("nombre", "Portátil"),
combinada
)
def combinada = _mongo.updates().combine(
_mongo.updates().set("cantidad", 42),
_mongo.updates().rename("otro", "mas")
)
coleccion.updateOne(
_mongo.filters().eq("nombre", "Portátil"),
combinada
)
Encontrar y actualizar
Con findOneAndUpdate() se encuentra y actualiza un documento de forma atómica, devolviendo el documento original (o null si no hay ninguno):
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const anterior = coleccion.findOneAndUpdate(
_mongo.filters().eq("nombre", "Portátil"),
_mongo.updates().set("cantidad", 42)
)
const anterior = coleccion.findOneAndUpdate(
_mongo.filters().eq("nombre", "Portátil"),
_mongo.updates().set("cantidad", 42)
)
anterior = coleccion.findOneAndUpdate(
_mongo.filters().eq("nombre", "Portátil"),
_mongo.updates().set("cantidad", 42)
)
anterior = coleccion.findOneAndUpdate(
_mongo.filters().eq("nombre", "Portátil"),
_mongo.updates().set("cantidad", 42)
)
val anterior = coleccion.findOneAndUpdate(
_mongo.filters().eq("nombre", "Portátil"),
_mongo.updates().set("cantidad", 42)
)
def anterior = coleccion.findOneAndUpdate(
_mongo.filters().eq("nombre", "Portátil"),
_mongo.updates().set("cantidad", 42)
)
Sustituir Documentos
Con replaceOne() se sustituye el documento completo (a diferencia de las actualizaciones, no puede contener operadores de actualización):
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
coleccion.replaceOne(
_mongo.filters().eq("nombre", "Portátil"),
_val.map()
.set("nombre", "Portátil")
.set("cantidad", 50)
.set("precio", 150)
.set("categoria", "destacado")
)
coleccion.replaceOne(
_mongo.filters().eq("nombre", "Portátil"),
_val.map()
.set("nombre", "Portátil")
.set("cantidad", 50)
.set("precio", 150)
.set("categoria", "destacado")
)
coleccion.replaceOne(
_mongo.filters().eq("nombre", "Portátil"),
_val.map()
.set("nombre", "Portátil")
.set("cantidad", 50)
.set("precio", 150)
.set("categoria", "destacado")
)
coleccion.replaceOne(
_mongo.filters().eq("nombre", "Portátil"),
_val.map()
.set("nombre", "Portátil")
.set("cantidad", 50)
.set("precio", 150)
.set("categoria", "destacado")
)
coleccion.replaceOne(
_mongo.filters().eq("nombre", "Portátil"),
_val.map()
.set("nombre", "Portátil")
.set("cantidad", 50)
.set("precio", 150)
.set("categoria", "destacado")
)
coleccion.replaceOne(
_mongo.filters().eq("nombre", "Portátil"),
_val.map()
.set("nombre", "Portátil")
.set("cantidad", 50)
.set("precio", 150)
.set("categoria", "destacado")
)
Para encontrar y sustituir de forma atómica, devolviendo el documento antiguo, utilice findOneAndReplace():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const anterior = coleccion.findOneAndReplace(
_mongo.filters().eq("nombre", "Portátil"),
_val.map()
.set("nombre", "Portátil")
.set("cantidad", 50)
)
const anterior = coleccion.findOneAndReplace(
_mongo.filters().eq("nombre", "Portátil"),
_val.map()
.set("nombre", "Portátil")
.set("cantidad", 50)
)
anterior = coleccion.findOneAndReplace(
_mongo.filters().eq("nombre", "Portátil"),
_val.map()
.set("nombre", "Portátil")
.set("cantidad", 50)
)
anterior = coleccion.findOneAndReplace(
_mongo.filters().eq("nombre", "Portátil"),
_val.map()
.set("nombre", "Portátil")
.set("cantidad", 50)
)
val anterior = coleccion.findOneAndReplace(
_mongo.filters().eq("nombre", "Portátil"),
_val.map()
.set("nombre", "Portátil")
.set("cantidad", 50)
)
def anterior = coleccion.findOneAndReplace(
_mongo.filters().eq("nombre", "Portátil"),
_val.map()
.set("nombre", "Portátil")
.set("cantidad", 50)
)
Eliminar Documentos
Con deleteOne() y deleteMany() se eliminan los documentos que coinciden con el filtro:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
coleccion.deleteOne(
_mongo.filters().eq("nombre", "Portátil")
)
coleccion.deleteMany(
_mongo.filters().eq("categoria", "inactivo")
)
coleccion.deleteOne(
_mongo.filters().eq("nombre", "Portátil")
)
coleccion.deleteMany(
_mongo.filters().eq("categoria", "inactivo")
)
coleccion.deleteOne(
_mongo.filters().eq("nombre", "Portátil")
)
coleccion.deleteMany(
_mongo.filters().eq("categoria", "inactivo")
)
coleccion.deleteOne(
_mongo.filters().eq("nombre", "Portátil")
)
coleccion.deleteMany(
_mongo.filters().eq("categoria", "inactivo")
)
coleccion.deleteOne(
_mongo.filters().eq("nombre", "Portátil")
)
coleccion.deleteMany(
_mongo.filters().eq("categoria", "inactivo")
)
coleccion.deleteOne(
_mongo.filters().eq("nombre", "Portátil")
)
coleccion.deleteMany(
_mongo.filters().eq("categoria", "inactivo")
)
Para encontrar y eliminar un documento de forma atómica, devolviendo el documento eliminado, utilice findOneAndDelete():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const anterior = coleccion.findOneAndDelete(
_mongo.filters().eq("nombre", "Tableta")
)
const anterior = coleccion.findOneAndDelete(
_mongo.filters().eq("nombre", "Tableta")
)
anterior = coleccion.findOneAndDelete(
_mongo.filters().eq("nombre", "Tableta")
)
anterior = coleccion.findOneAndDelete(
_mongo.filters().eq("nombre", "Tableta")
)
val anterior = coleccion.findOneAndDelete(
_mongo.filters().eq("nombre", "Tableta")
)
def anterior = coleccion.findOneAndDelete(
_mongo.filters().eq("nombre", "Tableta")
)
Para eliminar todos los documentos de la colección, pase un filtro vacío con la ayuda de _mongo.valToDoc():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
coleccion.deleteMany(_mongo.valToDoc(_val.map()))
coleccion.deleteMany(_mongo.valToDoc(_val.map()))
coleccion.deleteMany(_mongo.valToDoc(_val.map()))
coleccion.deleteMany(_mongo.valToDoc(_val.map()))
coleccion.deleteMany(_mongo.valToDoc(_val.map()))
coleccion.deleteMany(_mongo.valToDoc(_val.map()))
Contar Documentos
Con countDocuments() se obtiene el número de documentos de la colección, opcionalmente con un filtro. Por su parte, estimatedDocumentCount() es más rápido porque utiliza los metadatos de la colección, pero sin filtro:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const total = coleccion.countDocuments()
const totalPrincipal = coleccion.countDocuments(
_mongo.filters().eq("categoria", "ordenadores")
)
const estimado = coleccion.estimatedDocumentCount()
const total = coleccion.countDocuments()
const totalPrincipal = coleccion.countDocuments(
_mongo.filters().eq("categoria", "ordenadores")
)
const estimado = coleccion.estimatedDocumentCount()
total = coleccion.countDocuments()
totalPrincipal = coleccion.countDocuments(
_mongo.filters().eq("categoria", "ordenadores")
)
estimado = coleccion.estimatedDocumentCount()
total = coleccion.countDocuments()
totalPrincipal = coleccion.countDocuments(
_mongo.filters().eq("categoria", "ordenadores")
)
estimado = coleccion.estimatedDocumentCount()
val total = coleccion.countDocuments()
val totalPrincipal = coleccion.countDocuments(
_mongo.filters().eq("categoria", "ordenadores")
)
val estimado = coleccion.estimatedDocumentCount()
def total = coleccion.countDocuments()
def totalPrincipal = coleccion.countDocuments(
_mongo.filters().eq("categoria", "ordenadores")
)
def estimado = coleccion.estimatedDocumentCount()
Índices
Con la factoría _mongo.indexes() se crean índices para mejorar el rendimiento de las consultas. Para crear un índice basta con pasar las especificaciones a createIndex():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
coleccion.createIndex(
_mongo.indexes().ascending("cantidad")
)
coleccion.createIndex(
_mongo.indexes().compoundIndex(
_mongo.indexes().descending("precio"),
_mongo.indexes().ascending("cantidad")
)
)
coleccion.createIndex(
_mongo.indexes().ascending("cantidad")
)
coleccion.createIndex(
_mongo.indexes().compoundIndex(
_mongo.indexes().descending("precio"),
_mongo.indexes().ascending("cantidad")
)
)
coleccion.createIndex(
_mongo.indexes().ascending("cantidad")
)
coleccion.createIndex(
_mongo.indexes().compoundIndex(
_mongo.indexes().descending("precio"),
_mongo.indexes().ascending("cantidad")
)
)
coleccion.createIndex(
_mongo.indexes().ascending("cantidad")
)
coleccion.createIndex(
_mongo.indexes().compoundIndex(
_mongo.indexes().descending("precio"),
_mongo.indexes().ascending("cantidad")
)
)
coleccion.createIndex(
_mongo.indexes().ascending("cantidad")
)
coleccion.createIndex(
_mongo.indexes().compoundIndex(
_mongo.indexes().descending("precio"),
_mongo.indexes().ascending("cantidad")
)
)
coleccion.createIndex(
_mongo.indexes().ascending("cantidad")
)
coleccion.createIndex(
_mongo.indexes().compoundIndex(
_mongo.indexes().descending("precio"),
_mongo.indexes().ascending("cantidad")
)
)
Puede indicar a MongoDB qué índice utilizar en una consulta, con hint():
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentos = coleccion.find().hint(
_mongo.valToDoc(
_val.map().set("cantidad", 1)
)
).all()
const documentos = coleccion.find().hint(
_mongo.valToDoc(
_val.map().set("cantidad", 1)
)
).all()
documentos = coleccion.find().hint(
_mongo.valToDoc(
_val.map().set("cantidad", 1)
)
).all()
documentos = coleccion.find().hint(
_mongo.valToDoc(
_val.map().set("cantidad", 1)
)
).all()
val documentos = coleccion.find().hint(
_mongo.valToDoc(
_val.map().set("cantidad", 1)
)
).all()
def documentos = coleccion.find().hint(
_mongo.valToDoc(
_val.map().set("cantidad", 1)
)
).all()
Con min() y max() se limita el rango de valores del índice recorridos por la consulta:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentos = coleccion.find()
.min(
_mongo.valToDoc(
_val.map().set("cantidad", 10)
)
)
.max(
_mongo.valToDoc(
_val.map().set("cantidad", 50)
)
)
.all()
const documentos = coleccion.find()
.min(
_mongo.valToDoc(
_val.map().set("cantidad", 10)
)
)
.max(
_mongo.valToDoc(
_val.map().set("cantidad", 50)
)
)
.all()
documentos = coleccion.find()
.min(
_mongo.valToDoc(
_val.map().set("cantidad", 10)
)
)
.max(
_mongo.valToDoc(
_val.map().set("cantidad", 50)
)
)
.all()
documentos = coleccion.find()
.min(
_mongo.valToDoc(
_val.map().set("cantidad", 10)
)
)
.max(
_mongo.valToDoc(
_val.map().set("cantidad", 50)
)
)
.all()
val documentos = coleccion.find()
.min(
_mongo.valToDoc(
_val.map().set("cantidad", 10)
)
)
.max(
_mongo.valToDoc(
_val.map().set("cantidad", 50)
)
)
.all()
def documentos = coleccion.find()
.min(
_mongo.valToDoc(
_val.map().set("cantidad", 10)
)
)
.max(
_mongo.valToDoc(
_val.map().set("cantidad", 50)
)
)
.all()
Agregaciones
Para análisis más avanzados, aggregate() permite ejecutar un pipeline de agregación, donde cada etapa se define con la factoría _mongo.aggregates() y los acumuladores con _mongo.accumulators().
Por ejemplo, para agrupar los productos por categoría y sumar el precio de cada grupo:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentos = coleccion.aggregate(
_mongo.aggregates().match(
_mongo.filters().eq("categoria", "ordenadores")
),
_mongo.aggregates().group(
"$categoria",
_mongo.accumulators().sum("total", "$precio")
),
_mongo.aggregates().sort(
_mongo.sorts().descending("total")
)
).all()
const documentos = coleccion.aggregate(
_mongo.aggregates().match(
_mongo.filters().eq("categoria", "ordenadores")
),
_mongo.aggregates().group(
"$categoria",
_mongo.accumulators().sum("total", "$precio")
),
_mongo.aggregates().sort(
_mongo.sorts().descending("total")
)
).all()
documentos = coleccion.aggregate(
_mongo.aggregates().match(
_mongo.filters().eq("categoria", "ordenadores")
),
_mongo.aggregates().group(
"$categoria",
_mongo.accumulators().sum("total", "$precio")
),
_mongo.aggregates().sort(
_mongo.sorts().descending("total")
)
).all()
documentos = coleccion.aggregate(
_mongo.aggregates().match(
_mongo.filters().eq("categoria", "ordenadores")
),
_mongo.aggregates().group(
"$categoria",
_mongo.accumulators().sum("total", "$precio")
),
_mongo.aggregates().sort(
_mongo.sorts().descending("total")
)
).all()
val documentos = coleccion.aggregate(
_mongo.aggregates().match(
_mongo.filters().eq("categoria", "ordenadores")
),
_mongo.aggregates().group(
"$categoria",
_mongo.accumulators().sum("total", "$precio")
),
_mongo.aggregates().sort(
_mongo.sorts().descending("total")
)
).all()
def documentos = coleccion.aggregate(
_mongo.aggregates().match(
_mongo.filters().eq("categoria", "ordenadores")
),
_mongo.aggregates().group(
"$categoria",
_mongo.accumulators().sum("total", "$precio")
),
_mongo.aggregates().sort(
_mongo.sorts().descending("total")
)
).all()
Las etapas de agregación disponibles son las siguientes:
| Etapa | Descripción |
|---|---|
match(filtro) | Selecciona únicamente los documentos que coinciden con el filtro. |
group("$campo", acumuladores) | Agrupa los documentos por el campo y aplica los acumuladores. |
project(proyección) | Añade, elimina o modifica campos en los documentos. |
sort(ordenación) | Ordena los documentos. |
limit(n) | Limita a los primeros n documentos. |
skip(n) | Salta los primeros n documentos. |
count() | Cuenta el número de documentos. |
lookup("colección", "campoLocal", "campoExtranjero", "como") | Ejecuta un join con otra colección. |
Y los acumuladores más utilizados:
| Acumulador | Descripción |
|---|---|
sum("campo", "$expresión") | Suma de los valores. |
avg("campo", "$expresión") | Media de los valores. |
min("campo", "$expresión") | Valor mínimo. |
max("campo", "$expresión") | Valor máximo. |
first("campo", "$expresión") | Valor del primer documento. |
last("campo", "$expresión") | Valor del último documento. |
top("campo", ordenación, "$expresión") | Valor superior según la ordenación. |
bottom("campo", ordenación, "$expresión") | Valor inferior según la ordenación. |
En los acumuladores, la expresión con prefijo
$hace referencia al campo de un documento de entrada, por ejemplo"$precio".
Conversión entre Values y BSON
En ocasiones es necesario convertir entre los objetos _val de Netuno y documentos BSON de MongoDB:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const doc = _mongo.valToDoc(
_val.map().set("nombre", "Portátil")
)
const values = _mongo.docToVal(doc)
const doc = _mongo.valToDoc(
_val.map().set("nombre", "Portátil")
)
const values = _mongo.docToVal(doc)
doc = _mongo.valToDoc(
_val.map().set("nombre", "Portátil")
)
values = _mongo.docToVal(doc)
doc = _mongo.valToDoc(
_val.map().set("nombre", "Portátil")
)
values = _mongo.docToVal(doc)
val doc = _mongo.valToDoc(
_val.map().set("nombre", "Portátil")
)
val values = _mongo.docToVal(doc)
def doc = _mongo.valToDoc(
_val.map().set("nombre", "Portátil")
)
def values = _mongo.docToVal(doc)
Operaciones con Opciones
Las factorías *Options() del recurso _mongo devuelven los objetos de opciones estándar del driver de MongoDB, y puede encadenar sus métodos directamente. Por ejemplo, upsert(true) inserta el documento cuando el filtro no coincide con ningún documento existente:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const anterior = coleccion.findOneAndUpdate(
_mongo.filters().eq("nombre", "Monitor"),
_mongo.updates().set("cantidad", 8),
_mongo.findOneAndUpdateOptions().upsert(true)
)
const anterior = coleccion.findOneAndUpdate(
_mongo.filters().eq("nombre", "Monitor"),
_mongo.updates().set("cantidad", 8),
_mongo.findOneAndUpdateOptions().upsert(true)
)
anterior = coleccion.findOneAndUpdate(
_mongo.filters().eq("nombre", "Monitor"),
_mongo.updates().set("cantidad", 8),
_mongo.findOneAndUpdateOptions().upsert(true)
)
anterior = coleccion.findOneAndUpdate(
_mongo.filters().eq("nombre", "Monitor"),
_mongo.updates().set("cantidad", 8),
_mongo.findOneAndUpdateOptions().upsert(true)
)
val anterior = coleccion.findOneAndUpdate(
_mongo.filters().eq("nombre", "Monitor"),
_mongo.updates().set("cantidad", 8),
_mongo.findOneAndUpdateOptions().upsert(true)
)
def anterior = coleccion.findOneAndUpdate(
_mongo.filters().eq("nombre", "Monitor"),
_mongo.updates().set("cantidad", 8),
_mongo.findOneAndUpdateOptions().upsert(true)
)
Cuando el documento se inserta, findOneAndUpdate() devuelve null.
Las factorías de opciones disponibles son: insertOneOptions(), insertManyOptions(), updateOptions(), findOneAndUpdateOptions(), replaceOptions(), findOneAndReplaceOptions(), deleteOptions(), findOneAndDeleteOptions(), countOptions(), estimatedDocumentCountOptions(), dropCollectionOptions() y textSearchOptions().
Cerrar la Conexión
Al terminar, es una buena práctica cerrar la conexión con MongoDB:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_mongo.close()
_mongo.close()
_mongo.close()
_mongo.close()
_mongo.close()
_mongo.close()
Conclusión
Con el recurso _mongo, Netuno ofrece una abstracción low-code y políglota sobre el cliente oficial de MongoDB para Java, que permite trabajar con documentos, filtros, ordenaciones, proyecciones, actualizaciones, índices y agregaciones en JavaScript, Python, Ruby, Kotlin y Groovy.
Para más detalles sobre todos los métodos disponibles, consulte la documentación del recurso _mongo y de la clase MongoCollection.
¡Feliz desarrollo!