MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

MongoDB Schema Design - Votação em Postagens


A maneira comum de rastrear contagens de votos em geral seria manter o número de votos no documento post e atualizá-lo atomicamente ao enviar um novo valor para a matriz de votos.

Como é uma atualização única, você tem a garantia de que a contagem corresponderá ao número de elementos na matriz.

Se o número de agregações for fixo e o site estiver muito ocupado, você poderá estender esse paradigma e incrementar contadores adicionais, como um para mês, dia e hora, mas isso pode sair do controle muito rapidamente. Então, em vez disso, você pode usar o novo Aggregation Framework (disponível na versão dev 2.1.2, estará em produção na versão 2.2. É mais simples de usar do que Map/Reduce e permitirá que você faça os cálculos que deseja de maneira muito simples, especialmente se você tiver o cuidado de armazenar suas datas de votação como Tipo ISODate().

O pipeline típico para consulta de agregação para os principais captadores de votos deste mês pode ser algo assim:
today = new Date();
thisMonth = new Date(today.getFullYear(),today.getMonth());
thisMonthEnd = new Date(today.getFullYear(),today.getMonth()+1);

db.posts.aggregate( [
    {$match: { "Votes.votedate": {$gte:thisMonth, $lt:thisMonthEnd} } },
    {$unwind: "$Votes" },
    {$match: { "Votes.votedate": {$gte:thisMonth, $lt:thisMonthEnd} } },
    {$group: { _id: "$title", votes: {$sum:1} } },
    {$sort: {"votes": -1} },
    {$limit: 10}
] );

Isso limita a entrada do pipeline para postagens que têm votos combinando as datas dos votos com o mês que você está contando, "desenrola" a matriz para obter um documento por voto e, em seguida, faz um "agrupar por" equivalente somando todos os votos para cada título (Estou assumindo que o título é único). Em seguida, ele classifica decrescente por número de votos e limita a saída aos dez primeiros.

Você também pode agregar votos por dia (por exemplo) para aquele mês para ver quais dias são mais ativos para votação:
db.posts.aggregate( [
    {$match: { "Votes.votedate": {$gte:thisMonth, $lt:thisMonthEnd} } },
    {$unwind: "$Votes" },
    {$match: { "Votes.votedate": {$gte:thisMonth, $lt:thisMonthEnd} } },
    {$project: { "day" : { "$dayOfMonth" : "$Votes.votedate" }  } },
    {$group: { _id: "$day", votes: {$sum:1} } },
    {$sort: {"votes": -1} },
    {$limit: 10}
] );