MongoDB básico
Guía Básica de MongoDB
MongoDB es una base de datos NoSQL orientada a documentos que utiliza una estructura flexible de esquemas para almacenar datos en documentos JSON. Esta guía cubre los comandos básicos para manejar bases de datos y colecciones, además de operaciones comunes de CRUD, búsqueda avanzada y actualización en MongoDB.
Sintácticamente Mongo cambia un poco a lo que respecta de las BDD SQL, tenemos Documentos
en vez de Tuplas
y Colecciones
en vez de Tablas
.
Mostrar Bases de Datos y Selección de Base de Datos
-
Mostrar todas las bases de datos:
show dbsMuestra una lista de todas las bases de datos existentes.
-
Imprimir la base de datos actual:
dbMuestra la base de datos seleccionada actualmente.
-
Seleccionar (o crear) una base de datos:
use shopLa base de datos
shop
se creará solo cuando se haga la primera inserción.
Eliminar Bases de Datos y Colecciones
Para eliminar una base de datos o colección, simplemente selecciónala y usa los comandos correspondientes.
-
Eliminar una base de datos completa:
use nombreBaseDatosdb.dropDatabase() -
Eliminar una colección específica:
db.nombreColeccion.drop()
Crear Colección con Validación de Esquema
Podemos crear una colección con validación de esquema para asegurar que los documentos cumplan ciertos criterios:
db.createCollection("posts", { validator: { $jsonSchema: { bsonType: "object", required: ["title", "text", "creator"] } }})
Insertar Documentos
-
Insertar un solo documento:
db.coll.insertOne({name: "Max"}) -
Insertar varios documentos:
db.coll.insertMany([{name: "Max"}, {name: "Alex"}]) -
Insertar con
ordered: false
(continúa incluso si algunos documentos fallan):db.coll.insertMany([{name: "Max"}, {name: "Alex"}], {ordered: false}) -
Insertar Control de Escritura con
writeConcern
:db.coll.insert({name: "Max"}, {writeConcern: {w: "majority", wtimeout: 5000}})Control de Escritura: Puedes especificar el nivel de confirmación con
w
y el tiempo de espera conwtimeout
. -
Inserción de fechas:
db.coll.insert({date: ISODate()})
Buscar Documentos
-
Buscar un documento (devuelve el primero encontrado):
db.coll.findOne() -
Buscar varios documentos:
db.coll.find()Devuelve un cursor con los 20 primeros resultados.
-
Búsqueda con filtro y formato legible:
db.coll.find({name: "Max", age: 32}).pretty() -
Buscar con operadores de comparación:
db.coll.find({year: {$gt: 1970}}) // greater thanb.coll.find({"year": {$gte: 1970}}) // greater than or equaldb.coll.find({"year": {$lt: 1970}}) // lower thandb.coll.find({"year": {$lte: 1970}})db.coll.find({"year": {$ne: 1970}}) // not equaldb.coll.find({"year": {$in: [1958, 1959]}})db.coll.find({"year": {$nin: [1958, 1959]}}) -
Búsqueda con expresiones lógicas:
db.coll.find({$or: [{year: 1958}, {year: 1959}]})db.coll.find({name:{$not: {$eq: "Max"}}})db.coll.find({$or: [{"year" : 1958}, {"year" : 1959}]})db.coll.find({$nor: [{price: 1.99}, {sale: true}]})db.coll.find({$and: [{$or: [{qty: {$lt :10}}, {qty :{$gt: 50}}]},{$or: [{sale: true}, {price: {$lt: 5 }}]}]}) -
Búsqueda con expresiones regulares:
db.coll.find({name: /^Max/}) // comienza con "Max"db.coll.find({name: /^Max$/i}) // case insensitive -
Búsqueda en arreglos:
db.coll.find({tags: {$all: ["Realm", "Charts"]}}) // para que la búsqueda no sea literal y no busque el MISMO ORDENdb.coll.find({field: {$size: 2}}) // impossible to index - prefer storing the size of the array & update itdb.coll.find({results: {$elemMatch: {product: "xyz", score: {$gte: 8}}}}) -
Buscar con proyección para limitar los campos:
db.coll.find({x: 1}, {actors: 1}) // solo muestra el campo "actors" y "_id" -
Ordenar, omitir y limitar resultados:
db.coll.find().sort({year: 1}).skip(10).limit(3) -
Buscar con
readConcern
:db.coll.find().readConcern("majority") -
Buscar fechas:
db.coll.find({date: ISODate("2020-09-25T13:57:17.180Z")}) -
Contar Documentos:
db.coll.count({age: 32}) // estimation based on collection metadatadb.coll.estimatedDocumentCount() // estimation based on collection metadatadb.coll.countDocuments({age: 32}) // alias for an aggregation pipeline - accurate count
- Ejecutar una Operación con
explain()
para obtener estadísticas detalladas
El método explain()
ayuda a obtener detalles sobre cómo MongoDB ejecuta una consulta.
db.coll.find({name: "Max", age: 32}).explain("executionStats")
db.coll.find({"status.description": "description"}).pretty() // To access childrendb.coll.find({elements: ["Exact element"]}) // Para sacar un elemento literalmente con ese contenidodb.coll.distinct("name")
// Elementdb.coll.find({name: {$exists: true}})db.coll.find({"zipCode": {$type: 2 }})db.coll.find({"zipCode": {$type: "string"}})
// Aggregation Pipelinedb.coll.aggregate([ {$match: {status: "A"}}, {$group: {_id: "$cust_id", total: {$sum: "$amount"}}}, {$sort: {total: -1}}])
// Text search with a "text" indexdb.coll.find({$text: {$search: "cake"}}, {score: {$meta: "textScore"}}).sort({score: {$meta: "textScore"}})
// expresionsdb.coll.find({$expr: {$gt : ["val1", "val2"]}}) //Esto no funciona por que es literalmente una comparación de carácteresdb.coll.find({$expr: {$gt : ["$val1", "$val2"]}})db.coll.find({$expr: {$gt : [{$cond: {if: {$gte: ["$val1", 90]}, then: {$subtract: ["$val1", 10]}, else: "$val1" }}, "$target"]}})
// Cursorsdb.coll.find().next() //siempre nos va a devolver el artículo 21, para que devuelva el resto tenemos que usar un cursorconst dataCursor = db.coll.find()dataCursor.next();dataCursor.forEach(doc => {printjson(doc)})dataCursor.hasNext
// Projectionsdb.coll.find({"x": 1}, {"actors": 1}) // actors + _iddb.coll.find({"x": 1}, {"actors": 1, "_id": 0}) // actorsdb.coll.find({"x": 1}, {"actors": 0, "summary": 0}) // all but "actors" and "summary"
Actualizar Documentos
-
Actualizar un solo campo con
updateOne()
:db.coll.updateOne({_id: 1}, {$set: {year: 2016}}) -
Actualizar múltiples campos con
updateMany()
:db.coll.updateMany({year: 1999}, {$set: {decade: "90's"}}) -
Operaciones de incremento y multiplicación:
db.coll.update({_id: 1}, {$inc: {year: 5}})db.coll.update({_id: 1}, {$mul: {price: 1.25}}) -
Eliminar Campos (unset) o Renombrarlos (rename):
db.coleccion.update({"_id": 1}, {$unset: {"year": 1}})db.coleccion.update({"_id": 1}, {$rename: {"year": "date"}}) -
Actualizar Elementos en Arrays:
- Añadir un elemento:
db.coleccion.update({"_id": 1}, {$push: {"array": 1}})
- Quitar un elemento:
db.coleccion.update({"_id": 1}, {$pull: {"array": 1}})
- Añadir sin duplicados:
db.coleccion.update({"_id": 1}, {$addToSet: {"array": 2}})
db.coll.update({"_id": 1}, {$pop: {"array": 1}}) // last elementdb.coll.update({"_id": 1}, {$pop: {"array": -1}}) // first elementdb.coll.update({"_id": 1}, {$pullAll: {"array" :[3, 4, 5]}})db.coll.update({"_id": 1}, {$push: {scores: {$each: [90, 92, 85]}}})db.coll.updateOne({"_id": 1, "grades": 80}, {$set: {"grades.$": 82}})db.coll.updateMany({}, {$inc: {"grades.$[]": 10}}) // para que sea en todos los elementosdb.coll.update({}, {$set: {"grades.$[element]": 100}}, {multi: true, arrayFilters: [{"element": {$gte: 100}}]}) // "element" es un filtro - Añadir un elemento:
-
Buscar y actualizar con
findOneAndUpdate()
:db.coll.findOneAndUpdate({name: "Max"}, {$inc: {points: 5}}, {returnNewDocument: true}) -
Usar
upsert
para actualizar o crear si no existe:db.coll.updateOne({_id: 1}, {$set: {item: "apple"}, $setOnInsert: {defaultQty: 100}}, {upsert: true})
db.coll.update({"_id": 1}, {$min: {"imdb": 5}}) // si el valor seleccionado es menor que el que hay en la bdd se cambiadb.coll.update({"_id": 1}, {$max: {"imdb": 8}}) // si el valor seleccionado es mayor que el que hay en la bdd se cambiadb.coll.update({"_id": 1}, {$currentDate: {"lastModified": true}})db.coll.update({"_id": 1}, {$currentDate: {"lastModified": {$type: "timestamp"}}})
// Update manydb.coll.update({"year": 1999}, {$set: {"decade": "90's"}}, {"multi":true})db.coll.updateMany({"year": 1999}, {$set: {"decade": "90's"}})
// Replacedb.coll.replaceOne({"name": "Max"}, {"firstname": "Maxime", "surname": "Beugnet"})
// Savedb.coll.save({"item": "book", "qty": 40})
// Write concerndb.coll.update({}, {$set: {"x": 1}}, {"writeConcern": {"w": "majority", "wtimeout": 5000}})
elementMatch se usa para cuando tenemos un array que dentro del mismo están los valores que le pasemos y desperdigados por el resto de elementos
Eliminar Documentos
-
Eliminar Documentos Específicos:
db.coll.remove({name: "Max"}) -
Eliminar solo el primer documento encontrado:
db.coll.remove({name: "Max"}, {justOne: true}) -
Eliminar todos los documentos de una colección:
db.coll.remove({})Nota: Esto elimina todos los documentos pero no la colección en sí.
-
Eliminar y devolver el documento eliminado:
db.coll.findOneAndDelete({name: "Max"})
Funciones Adicionales y Configuración
-
Validación de Esquema Avanzada:
db.runCommand({collMod: 'posts',validator: {$jsonSchema: {bsonType: 'object',required: ['title', 'text', 'creator', 'comments'],properties: {title: {bsonType: 'string',description: 'must be a string and is required'},// más propiedades}}},validationAction: 'warn'}); -
Proyecciones:
- Incluir o excluir campos específicos en la consulta:
db.coleccion.find({"x": 1}, {"actors": 1}) // Incluye "actors"db.coleccion.find({"x": 1}, {"actors": 0}) // Excluye "actors"
- Incluir o excluir campos específicos en la consulta:
-
Ordenar, Saltar y Limitar Resultados:
db.coleccion.find({}).sort({"year": 1, "rating": -1}).skip(10).limit(3) -
Read Concern (Nivel de Lectura):
db.coleccion.find().readConcern("majority")
Restricciones de MongoDB y Tipos de Datos
-
Límites de Documento:
- Tamaño máximo de un documento: 16 MB.
- Máximo de niveles de anidación en un documento: 100 niveles.
-
Tipos de Datos Importantes:
- int32: Rango máximo de ±2,147,483,647.
- int64: Rango máximo de ±9,223,372,036,854,775,807.
- Decimal de alta precisión:
db.coleccion.insert({precio: NumberDecimal("12.99")})
Tipos de Datos en MongoDB
MongoDB admite varios tipos de datos con ciertos límites:
-
Enteros:
int32
(valor máximo: ±2,147,483,647).int64
(valor máximo: ±9,223,372,036,854,775,807).
-
Número decimal de alta precisión:
NumberDecimal("12.99")
es útil para cálculos exactos.
-
Arreglos y objetos:
- Los documentos deben ser <= 16 MB.
- Solo se permite una profundidad de anidación de hasta 100 niveles.
-
Convertir tipos de datos en controladores (ejemplo en Node.js):
const Long = require('mongodb').Long;db.collection('wealth').insert({value: Long.fromString("121949898291")});