‫Instrutor: Lembra-se de como temos
‫um campo para a classificação média em cada documento turístico?
‫Bem, até este ponto, esse campo não contém
‫nenhum dado significativo, certo?
‫Mas agora vamos realmente mudar
‫isso e calcular as classificações médias nesta aula.
‫Portanto, armazenar um resumo de um conjunto de dados
‫relacionado no conjunto de dados principal é, na verdade, uma técnica
‫muito popular em modelagem de dados que ainda não mencionei.
‫E essa técnica pode ser realmente útil
‫para evitar consultas constantes
‫do conjunto de dados relacionado.
‫Portanto, em nosso aplicativo, um ótimo exemplo dessa técnica
‫é armazenar a avaliação média e o número de
‫avaliações em cada passeio, para que não tenhamos que consultar
‫as avaliações e calcular essa média cada vez
‫que consultarmos todos os passeios, OK.
‫Por exemplo, isso pode ser muito
‫útil para uma página de visão geral do passeio
‫em nosso front-end, onde realmente não queremos exibir todos
‫os comentários, mas ainda queremos mostrar um resumo desses
‫comentários, como por exemplo, o número de avaliações e a média.
‫E, na verdade, já temos os campos para isso em
‫nosso esquema de passeio.
‫Bem aqui no começo, eu acho.
‫Sim, temos a média
‫e a quantidade de avaliações
‫aqui, mas agora eles são apenas alguns
‫números e, claro, não são a média real
‫e o número de avaliações, porque
‫nunca realmente calculamos isso em qualquer ponto do nosso
‫aplicativo, mas é exatamente isso que vamos mudar neste vídeo.
‫Portanto, agora vamos calcular a classificação média e também
‫o número de classificações de um passeio
‫cada vez que uma nova avaliação é adicionada a esse
‫passeio ou também quando uma avaliação é atualizada ou excluída, porque
‫essas são exatamente as situações
‫em que o número ou a média pode mudar, certo.
‫Então, como vamos realmente implementar isso?
‫Bem, de volta aqui no modelo de avaliação,
‫vamos criar uma nova
‫função que pegará um ID de
‫passeio e calculará a avaliação média e o número
‫de avaliações que existem em nossa coleção para aquele passeio exato.
‫Então, no final, a função irá até mesmo
‫atualizar o documento de tour correspondente.
‫Então, para usar essa função, usaremos
‫o middleware para basicamente chamar essa função toda vez
‫que houver uma nova revisão ou uma for
‫atualizada ou excluída, tudo bem.
‫Então, vamos começar escrevendo essa função e,
‫para isso, vamos escrever um método estático em nosso
‫esquema, e esse é um recurso do Mongoose
‫que ainda não usamos.
‫Portanto, usamos apenas o método de
‫instância, que podemos chamar em
‫documentos e também
‫são muito úteis, mas desta vez vamos realmente usar métodos estáticos.
‫OK.
‫Portanto, novamente, eles podem ser chamados diretamente no modelo, por
‫exemplo, como nesta revisão. calcStats, ok.
‫E a forma como isso funciona é, claro, revisar
‫o esquema e então. estática e, em seguida, o nome da função.
‫Portanto, calcA AverageRatings
‫é igual a uma função, que se lembra de pegar um tour
‫ID, e esse ID é claro para
‫o tour ao qual a revisão atual pertence.
‫E eu sei que neste ponto tudo parece
‫meio confuso, mas não se preocupe,
‫uma vez que tenhamos tudo
‫isso implementado e
‫também quando estivermos testando, fará muito sentido na prática, ok?
‫De qualquer forma, para agora fazer o
‫cálculo, vamos usar novamente o pipeline de agregação, certo.
‫Então, vamos lembrar disso em nosso controlador de ferramenta, então, bem
‫aqui, usamos o pipeline de agregação
‫para também criar algumas estatísticas como esta, ok.
‫Então usamos o método agregado, que chamamos diretamente
‫no modelo, ok.
‫Portanto, agora, em nosso método de instância, podemos fazer
‫exatamente a mesma coisa.
‫Portanto, em um método estático como este, essas palavras-chave na
‫verdade apontam para o modelo atual.
‫É por isso que podemos usar isso. agregado, porque lembre-se
‫de que precisamos chamar isso. agregar no modelo
‫diretamente, e é exatamente por isso
‫que estamos usando um método estático aqui em primeiro lugar.
‫Porque, novamente, agora aponta para o
‫modelo e precisamos chamar o agregado sempre no modelo, ok.
‫Então, no agregado, precisamos passar em uma
‫matriz de todos os estágios que queremos agregados, ok.
‫Então, o que queremos fazer primeiro?
‫Bem, a primeira etapa deve ser selecionar todas as avaliações
‫que realmente pertencem ao tour
‫atual que foi transmitido como o argumento.
‫OK.
‫Portanto, nosso primeiro estágio é um estágio de correspondência, lembre-se
‫disso,
‫e aqui passamos nosso objeto de
‫filtro e podemos dizer passeio igual a passeio,
‫mas realmente não precisamos disso, como
‫você já sabe, então vamos apenas remover isso parte, ou na verdade apenas
‫para torná-lo um pouco menos confuso aqui com
‫os nomes, vamos chamar este aqui de ID de tour, ok.
‫Então visite aqui,
‫ok.
‫Assim, selecionamos apenas
‫um tour que realmente queremos atualizar, ok.
‫Agora, na próxima fase, vamos calcular
‫as estatísticas eles próprios
‫e, para isso, usamos uma fase de grupos.
‫E na fase de grupo, lembre-se
‫de que o primeiro campo que precisamos especificar é o ID, portanto, _id e, em seguida,
‫o campo comum que
‫todos os documentos têm em comum
‫pelo qual desejamos agrupar e, portanto, esse será
‫novamente o passeio.
‫Assim como em nosso exemplo de cálculo de
‫estatística anterior, agrupamos por dificuldade.
‫Assim, calculamos as estatísticas para fácil e
‫estatísticas para médias
‫e, em seguida, estatísticas para passeios difíceis.
‫Portanto, neste exemplo, agrupamos todos os
‫passeios por dificuldade,
‫certo.
‫Mas aqui, é claro, estamos agrupando todos os tours
‫por tour.
‫Excelente.
‫Agora, o número de avaliações, lembre-se
‫de como fazemos
‫isso, então tudo o que fazemos é basicamente
‫adicionar um para cada turnê que
‫temos, então, cada turnê que foi correspondida na etapa anterior, tudo bem.
‫Portanto, se houver cinco documentos de revisão para o
‫tour atual, será adicionado um para cada um desses documentos.
‫Então, no final, o número de avaliações será
‫cinco, e novamente, porque é claro que temos cinco documentos de revisão.
‫Então isso faz sentido, certo?
‫Depois também a avaliação média, que assim como antes usamos o
‫operador médio e isso precisa estar dentro de um objeto
‫e
‫aqui o nome do
‫campo que é a avaliação, certo.
‫Portanto, lembre-se de que cada avaliação tem um campo de avaliação.
‫Então é daí que queremos calcular a média.
‫Ok, e é isso mesmo.
‫Portanto, o número e a média
‫das avaliações é exatamente o que queríamos calcular nesta agregação.
‫Agora, lembre-se de que isso realmente retorna
‫uma promessa e, portanto, precisamos aguardar isso e
‫armazená-lo em uma variável chamada estatísticas.
‫OK.
‫Em seguida, marque este aqui também
‫como assíncrono,
‫salve-o e agora precisamos usar essa variável de estatísticas.
‫Por enquanto, tudo o que realmente quero fazer
‫apenas para testar isso é registrar as estatísticas no console.
‫Console. estatísticas
‫de registro.
‫Ok, então, na etapa posterior, vamos realmente querer, como
‫mencionei antes, atualizar o documento de tour com essas
‫estatísticas, mas vou deixar
‫isso um pouco mais tarde, porque
‫por enquanto precisamos chamar esse
‫método aqui em algum lugar , porque
‫caso contrário, as estatísticas aqui nunca serão chamadas.
‫E lembre-se de como dissemos
‫no início que faríamos isso usando middleware
‫cada vez que uma nova revisão fosse criada.
‫Então, vamos implementar isso usando reviewSchema pré-salvamento e, em
‫seguida,
‫apenas nossa função normal de middleware aqui.
‫E lembre-se que neste tipo
‫de middleware essa palavra-chave aponta para o
‫documento que está sendo salvo no momento.
‫Então, isso aponta para a
‫revisão atual, ok.
‫Então, vamos querer chamar a função calcA
‫takingRating usando isso. tour, certo.
‫Agora, como vamos realmente chamar essa função?
‫Lembre-se de como
‫falei que esta função está disponível no modelo.
‫Então, basicamente como esta revisão
‫colocar. calcA AverageRatings e,
‫como eu disse, queremos usar isso. tour, ok.
‫E novamente, porque esta é a
‫revisão atual e este é o ID do tour que
‫passaremos dentro de calcA BudapRatings.
‫Agora, o problema é que, neste ponto aqui no código,
‫a variável de revisão ainda não foi definida.
‫Agora você pode pensar que a solução simples
‫seria simplesmente mover este código aqui após esta declaração de revisão, mas infelizmente
‫isso não vai funcionar, porque assim como
‫no Express, este código aqui basicamente é executado na
‫sequência em que é declarado.
‫Então, se colocássemos este código aqui
‫após a declaração de revisão, então este reviewSchema aqui
‫não conteria este middleware, porque então
‫apenas o declararíamos depois que
‫o modelo de revisão já foi criado, ok, mas felizmente
‫ainda há uma maneira de contornar isso e isso
‫é usar isso. construtor.
‫Então, isso aqui ainda aponta para o modelo.
‫Você sabe, basicamente, novamente, este é o documento atual
‫e o construtor é basicamente o
‫modelo que criou o documento.
‫Então, isso aqui representa
‫o tour e então podemos simplesmente fazer assim.
‫Em seguida, chame o próximo como sempre e é isso.
‫Portanto, vamos agora testar isso.
‫E para isso vou criar um novo passeio primeiro,
‫porque os outros que já temos
‫têm a média e o
‫número de classificações já calculados e
‫por isso queremos mesmo começar do zero aqui ao testar isto.
‫Então, para criar um novo tour, precisamos estar logados
‫como administradores, e acho que estamos atualmente, mas apenas para ter
‫certeza, vamos fazer isso de novo.
‫OK.
‫Portanto, este é o novo tour de teste.
‫Tudo bem, vamos remover isso aqui, eles não são obrigatórios,
‫e acho que estamos prontos para prosseguir.
‫Certo, e aqui você vê os padrões que definimos antes,
‫para que as avaliações sejam em
‫média cinco e a quantidade definida como zero, certo.
‫Agora, para criar uma nova revisão, na verdade
‫precisamos estar logados como um usuário regular, não
‫como um administrador.
‫Então, vamos pegar um usuário normal, digamos.
‫Então, vamos usar essa Laura aqui.
‫Então, Laura @ exemplo. com
‫e como mencionei anteriormente a senha é sempre a mesma.
‫Então vamos fazer isso e agora vamos criar uma nova revisão na turnê.
‫Agora vamos pegar o tour que criamos
‫anteriormente, colocar esse ID e colocá-lo aqui na URL.
‫Ok, então lembre-se de que esta rota
‫agora obtém automaticamente uma ID de tour da URL
‫e uma ID de usuário do usuário conectado no momento,
‫ok.
‫Então, vamos usar este como a primeira
‫avaliação, vamos enviá-lo, e agora quero dar uma olhada em nosso console.
‫Temos uma saída aqui, mas por algum motivo é
‫apenas como este array vazio.
‫Portanto, algo não deve estar funcionando aqui.
‫Então, vamos dar uma olhada no tour ID aqui apenas para
‫ter certeza de que estamos obtendo o valor correto aqui, ID e
‫também vamos comentar esta parte
‫aqui apenas para ver se talvez haja algum erro nesta
‫parte, então vamos tentar agora isso de novo.
‫Vou simplesmente adicionar o mesmo aqui novamente, ok.
‫Ok, agora realmente temos algo.
‫Portanto, temos esta análise
‫que criamos inicialmente.
‫Então, começa com este ac15,
‫mas o que acabei de criar é este 66d, ok.
‫Então, vamos dar uma olhada nisso aqui no Compass.
‫Portanto, precisamos ir para a última página.
‫Ok, então o que aparece em nosso console
‫é apenas este aqui, mas não o
‫segundo que acabamos de criar, ok.
‫Portanto, se agora criarmos
‫um terceiro, provavelmente veremos o primeiro e o segundo.
‫Então, vamos tentar isso.
‫OK.
‫Envie este e agora aqui em nossa saída,
‫na verdade recebo todos os três.
‫Então isso não faz muito sentido, mas de qualquer
‫maneira o ponto que eu queria enfatizar aqui
‫é que não devemos usar o
‫pre, mas em vez disso, devemos usar o middleware post save, ok.
‫E isso porque na pré-gravação,
‫a revisão atual ainda
‫não está realmente na coleção.
‫Portanto, quando fazemos essa correspondência aqui, ela não
‫deve ser capaz de aparecer na saída
‫aqui, porque, novamente, neste
‫momento, ela ainda não está realmente salva na coleção, ok.
‫Então é melhor usar post
‫aqui, porque naquele momento, é claro, todos
‫os documentos já estão salvos no banco de dados e
‫então é um ótimo
‫momento para realmente fazer esse cálculo com todas as revisões
‫e então armazenar o resultado no tour .
‫Ok, então não tenho
‫certeza de por que este aqui realmente apareceu
‫neste ponto, mas de qualquer maneira, vamos tentar agora com outro.
‫Esse é o quarto, e
‫agora o próximo não é uma função e, de fato,
‫como mencionei antes, o post middleware
‫não tem acesso ao próximo e,
‫portanto, é claro que não podemos chamá-lo, não podemos
‫usá-lo.
‫Tudo bem, então aqui temos nossa próxima classificação,
‫ok.
‫Portanto, agora também aparece aqui.
‫Portanto, não precisamos disso e agora podemos tentar
‫calcular nossas estatísticas com segurança aqui.
‫Salve e, na verdade, vamos
‫excluir todos esses comentários.
‫Então, basicamente, quero começar do zero, certo.
‫Portanto, todos
‫esses cinco comentários aqui devem ir e
‫agora estamos prontos para ir.
‫Então, vamos realmente criar este como o primeiro e
‫agora vamos em frente e dar uma olhada em nossas estatísticas e
‫lá vamos nós.
‫Portanto, este é o ID
‫do tour atual, o número de avaliações é
‫um e a média é, claro, três.
‫Portanto, se adicionarmos outro com a classificação de cinco poços, a
‫média deve ser quatro e devemos
‫ter o número de classificações igual a dois.
‫Então, vamos tentar isso e, de fato, como eu disse,
‫duas avaliações, média de quatro.
‫E só mais um só para ter certeza, vamos
‫adicionar outro com
‫cinco, e aí vamos nós.
‫Excelente.
‫Portanto, agora estamos calculando as estatísticas corretamente, mas é
‫claro que elas ainda não estão
‫sendo persistidas no documento de turnê atual.
‫Então, se viermos aqui no Compass para o passeio
‫que acabamos de criar,
‫provavelmente é o último aqui.
‫Sim, então nosso tour de teste ainda tem esses valores
‫padrão de 4. 5 e zero,
‫ok.
‫Então agora é hora de
‫realmente persistir as estatísticas calculadas neste documento de
‫passeio, certo.
‫E então vamos fazer isso.
‫Em primeiro lugar, para poder fazer
‫isso temos que exigir o modelo de tour, certo.
‫Portanto, a
‫excursão exige
‫e lá vamos nós.
‫Então, o que precisamos fazer é basicamente
‫encontrar o tour atual e atualizá-lo.
‫Então já fizemos isso muitas vezes,
‫findById e atualizar,
‫ok.
‫E o ID é, obviamente, o ID do tour que
‫foi passado para a função e,
‫em seguida, um objeto dos dados que realmente queremos atualizar.
‫Então, vamos obter esses nomes de campo a partir daqui.
‫Portanto, temos ratingsQuantity por
‫um lado.
‫Vamos colocá-lo aqui em um, por enquanto, para
‫não obtermos um erro e
‫a média das avaliações.
‫Novamente, para evitar erros, pois
‫agora quero vir
‫aqui dar uma olhada nessas estatísticas.
‫Então você vê que eles estão armazenados em um array, certo.
‫Portanto, precisamos ir para a primeira posição desse array, que é
‫onde este objeto está.
‫Estatísticas na posição zero e,
‫a partir daí, obtemos a propriedade de classificação final,
‫certo.
‫Então, este aqui.
‫E, claro, o mesmo para a classificação média.
‫OK.
‫E agora também precisamos aguardar.
‫Então, como sempre, isso retorna uma premissa e podemos aguardar.
‫Agora também poderíamos armazenar o resultado disso em uma
‫variável, mas realmente não precisamos do passeio.
‫Tudo o que queremos fazer é realmente
‫atualizá-lo e, portanto, não
‫armazenamos o valor dos resultados da premissa em qualquer lugar.
‫OK.
‫Então, vamos simplesmente tentar adicionar outra revisão aqui,
‫desta vez com uma péssima.
‫OK.
‫E antes de mais nada, vamos dar uma olhada nas estatísticas.
‫Obviamente, obtemos a classificação de quatro, o número de classificações
‫e a média de 3. 5
‫Então, agora, para ver se realmente funcionou,
‫vamos verificar o Compass ou também podemos usar ou
‫obter o ponto final do
‫passeio, ok.
‫Então precisamos do tour ID, que podemos
‫copiar daqui, colá-lo aqui, e agora é
‫o momento e de fato funcionou,
‫perfeito.
‫Isso é incrível, absolutamente fantástico.
‫Só mais uma vez para se divertir,
‫vamos adicionar outro comentário aqui.
‫OK.
‫Atualize este, e agora temos cinco e
‫nossa média subiu um pouco.
‫Excelente.
‫Então, vamos parar um segundo e recapitular o que fizemos aqui.
‫Então, começamos criando um método estático.
‫Então, toda essa função
‫aqui basicamente cria as estatísticas da média
‫e do número de avaliações para o ID
‫do tour para o qual a avaliação atual foi criada, ok.
‫E criamos essa função como um método
‫estático, porque precisávamos chamar a função de agregação
‫no modelo.
‫Portanto, em um método estático para esta variável
‫chama exatamente para um método.
‫Portanto, é muito útil nesses casos.
‫Então, construímos nosso pipeline de agregação aqui, onde selecionamos
‫todas as avaliações que correspondem ao ID
‫do tour atual e, em seguida, são calculadas as
‫estatísticas de todas essas avaliações.
‫Depois que isso
‫foi feito, salvamos as estatísticas do tour atual, certo.
‫Então, para realmente usar essa
‫função, nós a chamamos depois que uma nova revisão foi criada, ok.
‫Para isso, precisamos usar isso. construtor porque é
‫isso que aponta para o modelo atual.
‫Agora lembre-se de como dissemos que também queremos
‫atualizar as estatísticas sempre que uma revisão for editada ou excluída,
‫porque essas ações, é
‫claro, também influenciarão o número e a média.
‫No entanto, fazer isso é um pouco mais complexo.
‫Então, como este vídeo já está muito longo, vamos
‫deixar isso para o próximo.