‫Instructor: ¿Recuerda que tenemos un
‫campo para la calificación promedio en cada documento de viaje?
‫Bueno, hasta este punto, ese campo realmente no
‫contiene ningún dato significativo, ¿verdad?
‫Pero ahora cambiemos eso y
‫calculemos las calificaciones promedio en esta conferencia.
‫Por lo tanto, almacenar un resumen de un conjunto de
‫datos relacionados en el conjunto de datos principal es en realidad una técnica
‫muy popular en el modelado de datos que todavía no había mencionado.
‫Y esta técnica puede ser realmente útil
‫para evitar consultas constantes
‫del conjunto de datos relacionados.
‫Entonces, en nuestra aplicación, un gran ejemplo de esta técnica
‫es almacenar la calificación promedio y la cantidad de
‫calificaciones en cada recorrido, de modo que no tengamos que consultar
‫las reseñas y calcular ese promedio cada vez
‫que consultamos todos los recorridos, okey.
‫Por ejemplo, eso podría resultar muy
‫útil para una página de descripción general del recorrido
‫en nuestro front-end donde realmente no queremos mostrar todas las
‫reseñas, pero aún queremos mostrar un resumen de estas
‫reseñas, como por ejemplo, el número de calificaciones y la media.
‫Y de hecho ya tenemos los campos para eso en
‫nuestro esquema de viaje.
‫Así que aquí mismo al principio, creo.
‫Sí, tenemos el promedio
‫de calificaciones y la cantidad de
‫calificaciones aquí, pero en este momento son solo
‫algunos números y, por supuesto, no son el promedio
‫real ni la cantidad de calificaciones, porque
‫nunca calculamos eso en ningún momento en nuestra aplicación, pero
‫eso es exactamente lo que vamos a cambiar en este video.
‫Así que ahora mismo vamos a calcular la calificación
‫promedio y también el número de calificaciones
‫de un recorrido cada vez que se agrega una nueva revisión
‫a ese recorrido o también cuando se actualiza o elimina una revisión,
‫porque esas son exactamente las situaciones
‫en las que el número o el promedio podría cambiar, ¿no?
‫Entonces, ¿cómo vamos a implementar esto?
‫Bueno, aquí en el modelo de revisión, crearemos
‫una nueva función que
‫incluirá un ID de recorrido y
‫calculará la calificación promedio y la cantidad de
‫calificaciones que existen en nuestra colección para ese recorrido exacto.
‫Luego, al final, la función incluso actualizará
‫el documento de viaje correspondiente.
‫Luego, para usar esa función, usaremos
‫middleware para llamar básicamente a esta función cada vez
‫que haya una nueva revisión o que se actualice
‫o elimine una, está bien.
‫Así que comencemos ahora escribiendo esa función y
‫para eso vamos a escribir un método estático en
‫nuestro esquema, y esa es una característica de Mongoose
‫que aún no hemos usado.
‫Así que solo usamos el método
‫de instancia, que podemos invocar
‫en documentos y
‫también son muy útiles, pero esta vez realmente usaremos métodos estáticos.
‫Bueno.
‫Entonces, nuevamente, estos se pueden llamar directamente en el modelo,
‫por ejemplo, como esta revisión. calcStats, está
‫bien.
‫Y la forma en que esto funciona es, por
‫supuesto, reviewSchema y luego. estática y luego el nombre de la función.
‫Por lo tanto,
‫calcAverageRatings es igual a una función, que recuerda que incluye un ID de
‫recorrido, y ese ID es, por supuesto, para
‫el recorrido al que pertenece la revisión actual.
‫Y sé que en este punto probablemente todo suene
‫un poco confuso, pero no se preocupe
‫una vez que tengamos todo
‫esto implementado y también
‫cuando lo estemos probando, tendrá mucho sentido en la práctica, ¿de acuerdo?
‫De todos modos, para poder hacer ahora
‫el cálculo, usaremos nuevamente la canalización de agregación, ¿verdad?
‫Así que recordemos eso en nuestro controlador de herramientas, así que aquí
‫mismo usamos la canalización de agregación
‫para crear también algunas estadísticas como esta, de acuerdo.
‫Entonces usamos el método agregado, que llamamos directamente en
‫el modelo, está bien.
‫Así que ahora, en nuestro método de instancia, podemos
‫hacer exactamente lo mismo.
‫Entonces, en un método estático como este, estas palabras clave
‫en realidad apuntan al modelo actual.
‫Entonces es por eso que podemos usar esto. agregado, porque recuerde
‫que debemos llamar a esto. agregar en el modelo
‫directamente, y esa es exactamente la razón por
‫la que estamos usando un método estático aquí en primer lugar.
‫Porque nuevamente, esto ahora apunta al
‫modelo y necesitamos llamar al agregado siempre en el modelo, está bien.
‫Entonces, en el agregado, debemos pasar una serie
‫de todas las etapas que queremos en conjunto, está bien.
‫Entonces, ¿qué queremos hacer primero?
‫Bueno, el primer paso debería ser seleccionar todas las reseñas
‫que realmente pertenecen a la
‫gira actual que se pasó como argumento.
‫Bueno.
‫Entonces, nuestra primera etapa es una etapa de partido,
‫recuerda
‫eso, y aquí pasamos nuestro objeto
‫de filtro y podemos decir tour igual a
‫tour, pero realmente no lo necesitamos,
‫como ya sabes, así que eliminemos esto. parte, o simplemente para hacerlo
‫un poco menos confuso aquí con los nombres,
‫llamemos a este aquí ID de la gira, de acuerdo.
‫Así que tourId aquí, está
‫bien.
‫Así que, de esta manera,
‫solo seleccionamos un recorrido que realmente queremos actualizar, de acuerdo.
‫Ahora, en la siguiente etapa, calculemos
‫las estadísticas ellos mismos,
‫y para eso usamos una etapa de grupos.
‫Y en la fase de grupo,
‫recuerde que el primer campo que debemos especificar es el ID, entonces _id y luego
‫el campo común que
‫todos los documentos tienen en común
‫por el que queremos agrupar y ese será
‫nuevamente el recorrido.
‫Así que, al igual que en nuestro ejemplo anterior de
‫cálculo estadístico, lo agrupamos por dificultad.
‫Así que de esta manera calculamos las estadísticas para
‫recorridos fáciles y estadísticos
‫para medios y luego estadísticas para recorridos difíciles.
‫Entonces, en este ejemplo, agrupamos todos los recorridos
‫por su dificultad, está
‫bien.
‫Pero aquí, por supuesto, estamos agrupando todos los recorridos
‫por recorrido.
‫Excelente.
‫Ahora el número de calificaciones, recuerde
‫cómo lo hacemos,
‫así que todo lo que hacemos es básicamente
‫agregar una para cada gira que tenemos,
‫por lo que cada gira que coincidió en el paso anterior, está bien.
‫Entonces, si hay cinco documentos de revisión para el
‫recorrido actual, se agregará uno para cada uno de estos documentos.
‫Entonces, al final, el número de calificaciones será
‫cinco, y nuevamente, porque, por supuesto, tenemos cinco documentos de revisión.
‫Entonces eso tiene sentido, ¿verdad?
‫Luego también la calificación promedio, que al igual que antes usamos el
‫operador promedio y esto debe estar dentro de un objeto y
‫aquí
‫el nombre del campo
‫que es la calificación, a la derecha.
‫Así que recuerde que cada reseña tiene un campo de calificación.
‫De ahí es donde queremos calcular el promedio.
‫Está bien, y eso es todo.
‫Entonces, el número y el promedio
‫de calificaciones es exactamente lo que queríamos calcular en esta agregación.
‫Ahora tenga en cuenta que esto en realidad
‫devuelve una promesa y, por lo tanto, debemos esperarlo y
‫luego almacenarlo en una variable llamada stats.
‫Bueno.
‫Luego marque este aquí como asíncrono también,
‫déle un
‫guardado y ahora realmente necesitamos usar esa variable de estadísticas.
‫Por ahora, todo lo que realmente quiero hacer
‫para probar esto es registrar las estadísticas en la consola.
‫Consola. estadísticas
‫de registro.
‫Bien, entonces en el paso posterior realmente querremos, como mencioné
‫antes, luego actualizar el documento de viaje con estas estadísticas,
‫pero lo dejaré para un
‫poco más tarde, porque por ahora
‫realmente necesitamos llamar a este método
‫aquí en alguna parte. , porque de
‫lo contrario nunca se llamarán las estadísticas aquí.
‫Y recuerde cómo dijimos al
‫principio que haremos esto usando middleware cada
‫vez que se cree una nueva revisión.
‫Así que implementemos eso usando reviewSchema antes de guardar
‫y
‫luego solo nuestra función normal de middleware aquí.
‫Y recuerde que en este
‫tipo de middleware, esta palabra clave apunta
‫al documento que se está guardando actualmente.
‫Así que esto apunta a la
‫revisión actual, está bien.
‫Así que querremos llamar a la función
‫calcAverageRating usando this. gira, a la derecha.
‫Ahora, ¿cómo vamos a llamar realmente a esta función?
‫Recuerda cómo dije
‫que esta función está disponible en el modelo.
‫Así que, básicamente, me gusta
‫esta reseña. calcAverageRatings y luego,
‫como dije, queremos usar esto. gira, está
‫bien.
‫Y nuevamente, porque esta es la
‫revisión actual y este es el ID del recorrido
‫que pasaremos dentro de calcAverageRatings.
‫Ahora el problema es que en este punto aquí en el
‫código la variable de revisión aún no está definida.
‫Ahora podría pensar que la solución simple sería simplemente
‫mover este código aquí después de esta declaración de revisión, pero desafortunadamente eso
‫no va a funcionar, porque al igual que
‫en Express, este código aquí básicamente se ejecuta en la
‫secuencia en que se declaró.
‫Entonces, si pusiéramos este código aquí después
‫de la declaración de revisión, entonces este esquema de revisión
‫aquí no contendría este middleware, porque
‫solo lo declararíamos después de que
‫el modelo de revisión ya se haya creado, está bien, pero
‫afortunadamente todavía hay una forma de evitar esto y eso
‫es usar esto. constructor.
‫Entonces esto aquí todavía apunta al modelo.
‫Ya sabes, básicamente, nuevamente, este es el documento actual
‫y el constructor es básicamente el
‫modelo que creó ese documento.
‫Así que esto aquí
‫representa la gira y entonces podemos simplemente hacerlo así.
‫Luego llame a next como siempre y eso es todo.
‫Así que sigamos adelante y probemos esto.
‫Y para hacer eso, crearé una nueva gira primero,
‫porque las otras que ya tenemos
‫tienen el promedio y la
‫cantidad de calificaciones ya calculadas, por
‫lo que realmente queremos comenzar desde cero aquí cuando prueben esto.
‫Entonces, para crear un nuevo recorrido, debemos iniciar
‫sesión como administradores, y creo que actualmente lo estamos, pero
‫solo para asegurarnos, hagámoslo nuevamente.
‫Bueno.
‫Así que esta es la nueva gira de prueba.
‫Muy bien, eliminemos estos aquí, no son obligatorios, y
‫creo que con esto estamos listos.
‫Muy bien, y aquí puede ver los valores predeterminados que establecimos
‫antes, así que las calificaciones promedian
‫cinco y la cantidad se establece en cero, está bien.
‫Ahora, para crear una nueva revisión, en realidad
‫necesitamos iniciar sesión como un usuario regular, no
‫como un administrador.
‫Entonces, digamos que es un usuario normal.
‫Así que usemos a esta Laura aquí.
‫Así que Laura @ ejemplo. com
‫y como mencioné anteriormente, la contraseña es siempre la misma.
‫Así que hagámoslo y ahora crearemos una nueva reseña durante la gira.
‫Así que ahora obtengamos el recorrido que creamos anteriormente,
‫así que este ID y lo ponemos aquí en la URL.
‫Bien, y recuerde que esta ruta ahora
‫obtiene automáticamente un ID de recorrido de la URL
‫y un ID de usuario del usuario actualmente conectado, de
‫acuerdo.
‫Así que usemos esta como la
‫primera calificación, enviémosla y ahora quiero echar un vistazo a nuestra consola.
‫Tenemos una salida aquí, pero por alguna razón es
‫solo como esta matriz vacía.
‫Entonces, algo no debe estar funcionando aquí.
‫Así que echemos un vistazo a la ID del recorrido aquí
‫solo para asegurarnos de que estamos obteniendo el valor correcto aquí, ID y
‫también comentemos esta parte aquí
‫solo para ver si tal vez hay algún error en
‫esta parte, así que intentemos ahora de nuevo.
‫Simplemente agregaré el mismo aquí nuevamente, está bien.
‫Bien, ahora tenemos algo.
‫Así que tenemos esta revisión que
‫es la que creamos inicialmente.
‫Entonces comienza con este ac15,
‫pero el que acabo de crear es este 66d, está bien.
‫Así que echemos un vistazo a eso aquí en Compass.
‫Entonces tenemos que ir a la última página.
‫De acuerdo, entonces el que aparece en nuestra consola
‫es solo este de aquí, pero no el segundo
‫que acabamos de crear, de acuerdo.
‫Entonces, si ahora creamos un
‫tercero, probablemente deberíamos ver el primero y el segundo.
‫Así que intentemos eso.
‫Bueno.
‫Envíe este y ahora aquí, en
‫nuestro resultado, obtengo los tres.
‫Así que eso no tiene mucho sentido, pero de
‫todos modos el punto que quería hacer aquí
‫es que no deberíamos usar
‫pre, sino que deberíamos usar el middleware post save, de acuerdo.
‫Y eso se debe a que, antes
‫de guardar, la reseña actual
‫todavía no está realmente en la colección.
‫Por lo tanto, cuando hagamos esta coincidencia aquí,
‫no debería poder aparecer en la salida
‫aquí, porque nuevamente en este
‫momento no está realmente guardado en la colección todavía, de acuerdo.
‫Por lo tanto, es mejor usar
‫la publicación aquí, porque en ese momento,
‫por supuesto, todos los documentos ya están guardados en la base
‫de datos, por lo que
‫es un buen momento para hacer este cálculo con todas las revisiones
‫y luego almacenar el resultado en el recorrido. .
‫De acuerdo, no estoy
‫muy seguro de por qué este de aquí
‫apareció en este punto, pero de todos modos, probémoslo con otro.
‫Así que ese es el
‫cuarto, y ahora obtenemos que el siguiente no es una función y,
‫de hecho, como mencioné anteriormente, el middleware
‫de la publicación no tiene acceso al
‫siguiente y, por lo tanto, por supuesto, no podemos llamarlo, no
‫podemos usarlo.
‫De acuerdo, y aquí tenemos nuestra próxima calificación, de
‫acuerdo.
‫Así que ahora también aparece aquí.
‫Así que no necesitamos eso y ahora podemos intentar
‫calcular nuestras estadísticas con seguridad aquí.
‫Guárdelo y, de hecho, eliminemos
‫todas estas revisiones.
‫Así que básicamente quiero empezar de cero, está bien.
‫Entonces, todas
‫estas cinco revisiones aquí deberían estar listas y
‫ahora estamos listos para comenzar.
‫Así que creemos este como el primero
‫y ahora sigamos adelante, echemos un vistazo a nuestras estadísticas
‫y aquí vamos.
‫Así que esta es la ID
‫actual del tour, entonces el número de calificaciones es
‫uno y el promedio es, por supuesto, tres.
‫Entonces, si agregamos otro con la calificación de cinco, entonces el
‫promedio debería ser cuatro y deberíamos
‫tener el número de calificaciones igual a dos.
‫Así que intentemos eso y, de hecho, como dije,
‫dos calificaciones, promedio de cuatro.
‫Y solo otro solo para estar realmente seguro,
‫agreguemos otro con
‫cinco, y aquí vamos.
‫Excelente.
‫Así que ahora estamos calculando correctamente las estadísticas, pero,
‫por supuesto, aún no se
‫mantienen en el documento de viaje actual.
‫Entonces, si venimos aquí en Compass a la gira
‫que acabamos de crear,
‫probablemente sea la última aquí.
‫Sí, entonces nuestro recorrido de prueba, todavía tiene estos valores
‫predeterminados de 4. 5 y cero, está
‫bien.
‫Así que ahora es el
‫momento de conservar las estadísticas calculadas en este documento de
‫viaje, de acuerdo.
‫Y entonces hagámoslo.
‫En primer lugar, para poder
‫hacer eso, necesitamos el modelo de gira, ¿verdad?
‫Así que
‫el tour
‫requiere y ahí vamos.
‫Entonces, lo que tenemos que hacer es básicamente
‫encontrar el recorrido actual y luego actualizarlo.
‫Así que lo hicimos antes muchas veces,
‫findById y actualiza, está
‫bien.
‫Y el ID es, por supuesto, el ID del recorrido que
‫se pasó a la función y
‫luego un objeto de los datos que realmente queremos actualizar.
‫Así que obtengamos estos nombres de campo de aquí.
‫Así que tenemos ratingsQuantity por
‫un lado.
‫Pongámoslo aquí a uno por ahora solo
‫para que no obtengamos un
‫error y ratingsAverage.
‫De nuevo, para evitar errores,
‫porque ahora quiero venir
‫aquí y echar un vistazo a estas estadísticas.
‫Entonces ves que están almacenados en una matriz en realidad, está bien.
‫Así que tenemos que ir a la primera posición de esa matriz, que
‫es donde está este objeto.
‫Entonces, las estadísticas en la posición
‫cero y luego de allí obtenemos la propiedad de calificación final, está
‫bien.
‫Así que este de aquí.
‫Y luego, por supuesto, lo mismo para la calificación promedio.
‫Bueno.
‫Y ahora también tenemos que esperarlo.
‫Entonces, como siempre, esto devuelve una premisa y así podemos esperarlo.
‫Ahora también podríamos almacenar el resultado de esto en una variable,
‫pero realmente no necesitamos el recorrido en absoluto.
‫Todo lo que queremos hacer es actualizarlo realmente, por
‫lo que no almacenamos
‫el valor de los resultados de la premisa en ningún lugar.
‫Bueno.
‫Así que simplemente intentemos agregar otra reseña aquí,
‫esta vez con una terrible.
‫Bueno.
‫Y antes que nada, echemos un vistazo a las estadísticas.
‫Entonces, por supuesto, obtenemos la calificación de cuatro, por lo que el número
‫de calificaciones y el promedio de 3. 5.
‫Entonces, ahora para ver realmente si funcionó, echemos
‫un vistazo a Compass o también podemos usar u
‫obtener el punto final del recorrido,
‫de acuerdo.
‫Entonces necesitamos el ID de la gira, que
‫podemos copiar desde aquí, pegarlo aquí, y ahora
‫llega el momento y de hecho
‫funcionó, perfecto.
‫Eso es increíble, absolutamente fantástico.
‫Solo una vez más para divertirnos,
‫agreguemos otra reseña aquí.
‫Bueno.
‫Actualice este, y ahora obtenemos cinco y
‫nuestro promedio subió un poco.
‫Excelente.
‫Así que ahora tomemos un segundo y recapitulemos lo que hicimos aquí.
‫Entonces comenzamos creando un método estático.
‫Entonces, esta función completa aquí
‫básicamente para crear las estadísticas del promedio y
‫el número de calificaciones para el ID del
‫recorrido para el que se creó la revisión actual, está bien.
‫Y creamos esta función como un método
‫estático, porque necesitábamos llamar a la función agregada en
‫el modelo.
‫Entonces, en un método estático, esta variable llama
‫exactamente a un método.
‫Por eso es muy útil en estos casos.
‫Así que construimos nuestra canalización de agregación aquí, donde
‫seleccionamos todas las reseñas que coincidían con
‫el ID de viaje actual, y luego se calculan
‫las estadísticas de todas estas reseñas.
‫Luego, una vez hecho
‫esto, guardamos las estadísticas en el recorrido actual, de acuerdo.
‫Luego, para usar esta función,
‫la llamamos después de que se haya creado una nueva revisión, está bien.
‫Para eso necesitamos usar esto. constructor porque esto
‫es lo que apunta al modelo actual.
‫Ahora tenga en cuenta cómo dijimos que también queremos
‫actualizar las estadísticas cada vez que se edita o elimina una revisión,
‫porque estas acciones, por
‫supuesto, también influirán en el número y el promedio.
‫Sin embargo, hacerlo es un poco más complejo.
‫Entonces, dado que este video ya se está ejecutando
‫bastante, dejémoslo para el siguiente.