Muy decepcionante el curso a nivel de estructuración, deberian trabajar en un curso de Mongodb mas estructurado, una pena que aun lo lo hayan rectificado.
Introducción
Qué aprenderás sobre MongoDB
Bases de datos NoSQL
Definición de MongoDB y su ecosistema (herramientas de uso)
MongoDB Atlas
Instalación MongoDB en Windows
Instalación MongoDB Mac/Linux
Mongo Shell, configuración de clientes
MongoDB + Drivers
Operaciones CRUD
Bases de datos, Colecciones y Documentos en MongoDB
Operaciones CRUD desde la consola de MongoDB
Operaciones CRUD desde Compass
Esquemas y relaciones
Tipos de datos
¿Qué son los esquemas y las relaciones?
Relaciones entre documentos
Profundización de queries dentro de MongoDB
Operadores para realizar queries y proyecciones
Usando operadores para realizar Updates en arreglos
Operaciones avanzadas con Agregaciones
Python con MongoDB (opcional)
Configuración e instalación de dependencias para el proyecto PlatziMongo
Operaciones CRUD con Python y Pymongo
Diseñando el esquema de clases, cursos y carreras
Ejecución de queries
Relaciones
Consultas más rápidas con Índices
Recomendaciones para poner en producción tu cluster de Atlas
Recomendaciones de Arquitectura y Paso a Producción
Nuestra base de datos en un cluster de producción
Conclusiones
Resumen y Conclusiones
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Aportes 48
Preguntas 3
Muy decepcionante el curso a nivel de estructuración, deberian trabajar en un curso de Mongodb mas estructurado, una pena que aun lo lo hayan rectificado.
Todo iba bien hasta el video 18, despues se pierde el hilo y despues seguirlo con python,
Hasta aquí llego con este curso de Python, perdón de MongoDB. Esta muy mal estructurado y explicado. Platzi por favor revisen este curso, necesita ser renovado.
Hasta el Momento no creo que el curso este mal estructurado, solo pienso que necesita varios conocimientos básicos pero previos en temas como :
RESTful
JSON
PYTHON
How to build a API.
Creo que la mejor forma de enseñar esta tecnología es aplicándola a un caso real como se hace en este curso y para los que no les gusta tanto python deberían verlo como la oportunidad de un 2x1.
Esto no es una Clase… más bien parece un tutorial … y existen mejores turoriales por internet … !!!
Aunque no se Python, al menos entendí el concepto.
No logro entender ¿por qué tienen que usar un lenguaje de programación a un tema netamente de base de datos? ¿cuál es el objetivo? creo que con eso se pierde el enfoque y el rumbo del curso; lo digo porque vengo del curso de fundamentos de bases de datos y el profesor NUNCA utilizó una línea de código de lenguaje de programación, todo fue desde la consola e interfaz gráfica del programa… y ojo, se trabajo un proyecto claro, real y bien estructurado. Señores Platzi, no nos hagan esto. Ahora bien, hasta donde tengo entendido, Mongo está basado en javascript, ¿por qué no usaron javascript?
¿este tipo de contenido es analizado antes de ser lanzado? porque si es así, algo está pasando en ese proceso. Es lo que considero.
Por si algún curioso (Como yo) quiere saber para qué sirve específicamente el método $addToSet de la documentación oficial
Si quieren la documentación para el $pull Pull
def consultar_curso_por_id_proyeccion(id_curso, proyeccion=None):
return db.cursos.find_one({'_id': ObjectId(id_curso)}, proyeccion)#Regresa el curso solo con los campos indicados.
def agregar_curso(json):
curso = consultar_curso_por_id_proyeccion(json['id_curso'], proyeccion={'nombre': 1}) #Solo guarda en carreras el nombre y el id de la clase.
return str(db.carreras.update_one({'_id': ObjectId(json['id_carrera'])}, {'$addToSet': {'cursos': curso } }).modified_count)#Agrega el curso en la colección de carreras.
def borrar_curso_de_carrera(json):
return str(db.carreras.update_one({'_id': ObjectId(json['id_carrera'])}, {'$pull': {'cursos': {'_id': ObjectId( json['id_curso'] ) } } } ).modified_count) #Pull saca un elemento de la pila.
Lamentablemente el curso es malo, claro es mi punto de vista pero no pago para recibir esta calidad sabiendo que hay contenido gratuito que es mucho mejor que lo que me esta dando Platzi, por ejemplo:
https://university.mongodb.com/courses/catalog
No es el primer curso de Platzi que me pasa lo mismo por las mismas u otras razones. Deberían preocuparse mas por la calidad que por la rapidez.
No me gusta que hayan metido una app en Python en el medio de un curso de MongoDB. No me interesa Python, no me interesa pymongo, me interesa MONGODB. Hubiese sido más productivo el curso si todas las consultas se hiciera por consola o con Mongo Compass y no desde una librería de python o de X lenguaje. Se desvió el objetivo del curso con estos videos que ni siquiera pierdo tiempo mirando.
Excelente clase. Algunas cosas no las entedía muy bien, pero leyendo la documentación del driver pymongo me aclaró todas las dudas.
Esta muy bien documentado el driver:
Si el objetivo es construir una carrera en el mundo del desarrollo tenemos que acostumbrarnos a lidiar con la permanente incertidumbre y desarrollar nuestras capacidades para encontrar respuestas. Esta es la constante del día a día y tenemos que agarrarle el gusto, sobre todo a esa sensación de satisfacción cuando finalmente encontramos la respuesta 😊. No se desanimen. Solo es cuestión de tiempo para que lleguen a comprender algo que parece complicado
Tengo una duda, cuando uso el método para borrar curso de una carrera no hace nada, es decir sale como borrados: 0, en postman estoy usando la URL: http://127.0.0.1:5000/carreras/agregar-curso
Anexo también el código, pero de verdad no encuentro el error.
def borrar_curso_de_carrera(json):
return str(db.carreras.update_one({'_id': ObjectId(json['id_carrera'])}, {'$pull': {'cursos': {'_id': ObjectId(json['id_curso'])}}}).modified_count)
# $pull saca un elemento dentro del arreglo```
tenía un pequeño error pero ya lo solucione
me salía:
TypeError: id must be an instance of (bytes, str, ObjectId), not <class 'dict'>
y era debido a que cuando vamos a agregar un curso a una carrera hacemos uso de la funcion consultar_curso_por_id_proyeccion la cual recibe 2 parametros el id y la proyeccion
mi error era que estaba convirtiendo 2 veces el _id en un ObjectId y si bien se puede ver, solo se necesita pasarle el id como un string ya que la funcion consultar_curso_por_id_proyeccion
se encarga de ello
Les comparto el código de borrar_curso_de_carrera()
def borrar_curso_de_carrera(json):
filter = {'_id': ObjectId(json['id_carrera'])}
# $pull operator delete an element from array inside the document
set = { '$pull': { 'cursos': {'_id': ObjectId(json['id_curso'])} }}
return str(db.carreras.update_one( filter, set).modified_count)
curso mal de mogoDB de hace 3 años y ni se molestan en actualizar… ah pero te metemos miles de cursos que nadie pidio de leguaje inclusivo porque eso si es el futuro…
Todo iba bien al principio, pero conforme fue avanzando, el curso fue tedioso ya que las explicaciones no están detalladas
Curioso leer todos estos comentarios de quejas, a mi me ha parecido un buen curso de introducción a Mongo. Tengo conocimientos de python quiza por eso no se me complicó, pero la verdad es que me funciona bastante bien la estructura.
El curso iba bien pero desde la clase “Configuración e instalación de dependencias para el proyecto platzi-mongo” se pierde el interés mejoren esto por favor, hagan un curso con una estructura mas seria y didáctica…
código:
from flask import Flask
from flask import request
from pymongo import MongoClient
from bson.json_util import dumps
from bson import ObjectId
import json
# client = MongoClient('localhost:27017')
client = MongoClient(
'mongodb+srv://[usuario]:[clave]@curso-platzi-kuuzl.mongodb.net/test')
db = client.platzi
app = Flask(__name__)
@app.route("/")
def hello():
return "Welcome to Python Flask! platzi-mongo2"
# CREATE CARRERA
@app.route("/carreras", methods=['POST'])
def create_carrera():
try:
data = json.loads(request.data)
nombre = data['nombre']
descripcion = data['descripcion']
if nombre and descripcion:
# status = db.carreras.insert_one(data)
# return dumps({'message' : 'SUCCESS'})
return dumps(db.carreras.insert_one(data).inserted_id)
except Exception as e:
return dumps({'error': str(e)})
# READ TODAS LAS CARRERAS
@app.route("/carreras", methods=['GET'])
def read_carrera():
try:
carreras = db.carreras.find()
return dumps(carreras)
except Exception as e:
return dumps({'error': str(e)})
# READ UNA CARRERA POR id
@app.route("/carreras/<id>", methods=['GET'])
def read_carrera_id(id):
try:
pageid = id
return dumps(db.carreras.find_one({'_id': ObjectId(pageid)}))
except Exception as e:
return dumps({'error': str(e)})
# UPDATE CARRERA
@app.route("/carreras", methods=['PUT'])
def update_carrera():
try:
data = json.loads(request.data)
nombre = data['nombre']
_id = data['_id']
descripcion = data['descripcion']
if nombre and descripcion:
status = db.carreras.update_one({'_id': ObjectId(_id)}, {
'$set': {'nombre': nombre, 'descripcion': descripcion}})
return str(status.modified_count)
except Exception as e:
return dumps({'error': str(e)})
# DELETE UNA CARRERA POR id
@app.route("/carreras/<id>", methods=['DELETE'])
def delete_carrera_id(id):
try:
pageid = id
status = db.carreras.delete_one({'_id': ObjectId(pageid)})
return str(status.deleted_count)
except Exception as e:
return dumps({'error': str(e)})
# home function
@app.route('/profile/<int:id>')
def myProfile(id):
return 'The project page ' + str(id)
# CREATE CURSO
@app.route("/cursos", methods=['POST'])
def create_curso():
try:
data = json.loads(request.data)
nombre = data['nombre']
descripcion = data['descripcion']
if nombre and descripcion:
# id = str(db.cursos.insert_one(data).inserted_id)
# return dumps({"_id":id})
return dumps(db.cursos.insert_one(data).inserted_id)
except Exception as e:
return dumps({'error': str(e)})
# READ TODAS LOS CURSOS
@app.route("/cursos", methods=['GET'])
def read_curso():
try:
cursos = db.cursos.find()
return dumps(cursos)
except Exception as e:
return dumps({'error': str(e)})
# READ UN CURSO POR id
@app.route("/cursos/<id>", methods=['GET'])
def read_curso_id(id):
try:
pageid = id
return dumps(db.cursos.find_one({'_id': ObjectId(pageid)}))
except Exception as e:
return dumps({'error': str(e)})
# UPDATE CURSO
@app.route("/cursos", methods=['PUT'])
def update_curso():
try:
data = json.loads(request.data)
_id = data['_id']
nombre = data['nombre']
descripcion = data['descripcion']
# eliminar _id del JSON para que no genere un error al actualizar
del data['_id']
filtro = {'_id': ObjectId(_id)}
actualizar = {'$set': data}
if nombre and descripcion:
status = db.cursos.update_one(filtro, actualizar)
return str(status.modified_count)
except Exception as e:
return dumps({'error': str(e)})
# DELETE UN CURSO POR id
@app.route("/cursos/<id>", methods=['DELETE'])
def delete_curso_id(id):
try:
pageid = id
status = db.cursos.delete_one({'_id': ObjectId(pageid)})
return str(status.deleted_count)
except Exception as e:
return dumps({'error': str(e)})
def consultar_curso_por_id_proyeccion(id_curso, proyeccion=None):
return db.cursos.find_one({'_id': ObjectId(id_curso)}, proyeccion)
# AGREGAR CURSO A CARRERA
@app.route("/carreras/agregar-curso", methods=['PUT'])
def add_curso_to_carrera():
try:
data = json.loads(request.data)
curso = consultar_curso_por_id_proyeccion(
data['id_curso'], proyeccion={'nombre': 1})
return str(db.carreras.update_one({'_id': ObjectId(data['id_carrera'])}, {'$addToSet': {'cursos': curso}}).modified_count)
except Exception as e:
return dumps({'error': str(e)})
# REMOVER CURSO A CARRERA
@app.route("/carreras/agregar-curso", methods=['DELETE'])
def remove_curso_from_carrera():
try:
data = json.loads(request.data)
filtro = {'_id': ObjectId(data['id_carrera'])}
remove = {'$pull': {'cursos': {'_id': ObjectId(data['id_curso'])}}}
return str(db.carreras.update_one(filtro, remove).modified_count)
except Exception as e:
return dumps({'error': str(e)})
creo que el curso no da para mas a que es basico, fuera uno de administración seria mas por el lado de configuración y todo eso.
averiguare mas en la documentacion sobre $addToSet
El cursos me parece bueno, creo debemos tener claro los conceptos lógica de programación, ademas un buen programador acepta los retos y con un poco de paciencia se resuelven
Funciones:
def consultar_curso_por_id_proyeccion(id_curso, proyeccion=None):
return str(db.cursos.find_one({'_id': ObjectId(id_curso)}, proyeccion))
def agregar_curso(json):
curso = consultar_curso_por_id(json['id_curso'], proyeccion={'nombre': 1})
return str(db.carreras.update_one({'_id': ObjectId(json['id_carrera'])}, {'$addToSet': {'cursos': curso}}).modified_count)
def borrar_curso_de_carrera(json):
return str(db.carreras.update_one({'_id': ObjectId(json['id_carrera'])}, {'pull': {'cursos': {'_id': ObjectId(json['id_curso'])}}}).modified_count)
Malo este curso, totalmente decepcionado. Buscaré otro curso en Udemy
Siguiendo el ejemplo de alumnos, podríamos tener un documento que contenga las direcciones (calle, piso etc.), y podríamos conseguirlo de dos formas: con una relación incrustada o con una relación referenciada.
En una relación incrustada, insertaríamos la dirección dentro del documento de alumnos, como por ejemplo:
db.alumnos.insert(
{
nombre : "Hugo",
edad: 29,
direccion: {
calle: "Avenida del automovil",
numero: 2
}
}
)
Pero también podríamos almacenar esa información en otro documento y llamar a esa información con dos comandos:
{
"_id":ObjectId("52ffc33cd85242f436000001"),
"nombre": "Hugo",
edad: 23,
"direccion_ids": [
ObjectId("52ffc4a5d85242602e000000"),
ObjectId("52ffc4a5d85242602e000001")
]
}
Y posteriormente podríamos llamarlo así:
var addresses = db.direcciones.find({"_id":{"$in":result["direccion_ids"]}})
Es común que la información que almacenamos en nuestra base de datos esté conectada entre sí. Esto se denomina relaciones. En una base de datos podemos encontrar distintos tipos de relaciones, mismas que clasificamos por la cantidad de información que se conecta entre sí. Por ejemplo, cuando un curso puede tener muchos vídeos, decimos que es una relación de uno a muchos, cuando un usuario puede tener un registro de configuración, podemos decir que es una relación uno a uno.
Las relaciones son un problema por sí mismas, y son aún más difíciles de comprender en el contexto de una base de datos como la de MongoDB a la que usualmente nos referimos como una base de datos no relacional.
La primer regla que tienes que considerar es que si en tu información existen muchas relaciones, quizás debas considerar utilizar un motor de bases de datos hecho para éstos casos como una base de datos relacional.
La segunda regla es que sí puedes tener relaciones en una base de datos noSQL como la de MongoDB, pero existen ciertas consideraciones importantes, para entenderlas necesitas saber que existen dos formas principales a través de las cuales puedes definir una relación en MongoDB.
Campos de referencia : este enfoque es el más parecido a las relaciones en una base de datos SQL donde se establece un campo que indica con qué otro registro está conectada la información, este es un campo especial, una llave foránea.
Dicho campo modifica el comportamiento interno de la tabla y ofrece una serie de optimizaciones y beneficios al momento de consultar las relaciones.
En una base de datos no relacional también podemos definir un campo que conecte con otro, sin embargo, este campo no es igual a una llave foránea en una base de datos relacional. Aunque a través de este campo podemos establecer y consultar relaciones, no existen modificaciones de rendimiento interno.
El mayor beneficio de usar este enfoque es que es el más sencillo de usar si tienes experiencia previa con bases de datos relacionales.
Subdocumentos : La mayor ventaja del uso de un motor no relacional como el de MongoDB, es que el rendimiento de lectura es mucho mayor en comparación con el de un motor relacional. Esta diferencia se logra a través de la eliminación de operaciones costosas, entre ellas las operaciones JOIN que nos permiten relacionar información.
La manera en que podemos solucionar este problema, respetando el enfoque no relacional del motor es a través del uso de subdocumentos.
Es importante recordar que, a diferencia del trabajo con bases de datos relacinoales, en una base de datos noSQL como la de MongoDB, no hay un proceso de normalización, en términos prácticos: la información puede estar repetida.
Este punto es clave para entender el uso de subdocumentos, donde al registrar un dato que puede estar relacionado con otro, además de registrar el documento en su colección correspondiente, podemos duplicarlo y agregarlo como un subdocumento del documento con el que está relacionado.
En un ejemplo práctico, el documento Curso podría contener una propiedad vídeos donde se guarden todos los documentos con los registros de los vídeos del curso. Si por alguna razón necesitamos listar todos los vídeos, podríamos duplicar estos documentos en una colección distinta a la de cursos.
Es importante recordar que MongoDB nos permite guardar colecciones o arreglos dentro de un documento, de hecho, existen operaciones hechas para el trabajo con arreglos.
Entendido
La verdad este curso me ha parecido bueno para comenzar a adentrarme a MongoDb y justamente la intensión que tenía era de implementarlo a nivel de Backend con Python y Flask, asi que me vino como anillo al dedo. Cheers Profe!
agregar curso
Como podría eliminar un valor null en el array de cursos. Tenía un id de un curso que ya estaba eliminado y me agrego un valor null al array, arregle lo del id del curso, todo me funciono bien, pero el valor null se queda en el array.
Funciono el ejemplo.
Todo ok! Esta bueno implementarlo en un lenguaje estas practicas, y mas de uno que no se, es un desafío que afrontar!
No se pongan trabas por ser python, lo importante es entender como ejecuta los metodos de MongoDB y los comandos, operadores y consultas serian igual en cualquier otro de los lenguajes que el menciono. uso python quizas por que le parecio mas practico pero lo escencial es entender la estructura de mongo.
No me funciona la parte de borrar curso de carrera aunque lo haga igual, a alguien le pasa lo mismo?
def borrar_curso_de_carrera(json):
return str(db.carreras.update_one({'_id': ObjectId(json['id_carrera'])}, {'$pull': {'cursos': {'_id': ObjectId(json['id_curso'])}}}).modified_count)
def agregar_curso(json):
curso = consultar_curso_por_id_proyeccion(json['id_curso'], proyeccion ={'nombre':1})
return str(db.carreras.update_one({'_id': ObjectId(json['id_carrera'])}, {'$addToSet':{'cursos':curso}}).modified_count)
De acuerdo con la documentacion de MongoDB:
El operador $pull remueve, de un arreglo existente, todas las instancias que coincidan con el valor o valores que especifiquemos en la condición,
En nuestro caso, borrara de todos los cursos que coincidan con el id del curso dentro de la colección de cursos.
¯\_(ツ)_/¯
Todo estuvo muy bueno hasta que dijeron que instalaran Python yo vengo de aprender node, no tengo ningun conocimiento del lenguaje y pensar seguir cada uno de los cambios en el codigo me es frustrante, sugiero una actualizacion del curso.
consultar curso por id proyección
Muy mal estructurado el curso,en Udemy esta mejor estructurados y mejor explicado
Ok, esto de python esta bien raro, pero realice todo en la consola y esta genial, me encanto, creo que con solo explicar un poco mas el que se pueda hacer en la consola facilita mucho. Extra: Se pueden hacer variables temporales por sesion en la consola de mongo, por ejemplo la variable donde hacemos la proyeccion.
var curso = db.cursos.findOne({'_id': ObjectId('601d6019c98acf780cf0279c')}, {'nombre': 1})
con esto hacemos el update de carreras
db.carreras.updateOne({'_id': ObjectId('601c1bc70e600f1a6e6ba117')},{'$addToSet': {'cursos': curso}})
y listo.
Igualmente sirve para el $pull
Les comparto el código de agregar_curso()
curso = consultar_curso_por_id_proyeccion(json['id_curso'], projection={ 'nombre':1 })
filter = {'_id': ObjectId(json['id_carrera'])}
# We use $addToSet tu push a new element in array collection inside the document
set = { '$addToSet': { 'cursos': curso }}
return str(db.carreras.update_one( filter, set).modified_count)```
Leo muchos comentarios negativos sobre el curso pero dejaré mi apreciación. Noto que los que hacen este tipo de comentarios, solo les falta conocimientos de otras áreas las cuales requieren antes de ver este curso. Es normal, este tema, aún para ser intruductorio requiere bastante conocimiento. Como yo ya tenía todos esos conocimientos, me fue muy fácil seguir el curso y la verdad me gustó, era la introducción que esperaba de mongodb.
Si se les hace dificil seguir el curso, tomen los demás cursos que están en platzi sobre los temas en los que tienen dificultad: Postma, python básico, conceptos básicos de bd, etc.
Éxitos a todos, no se rindan y no paren de aprender.
Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Regístrate o inicia sesión para participar.