sql >> Database >  >> NoSQL >> MongoDB

MongoDB Schema Design - Stemmen op berichten

De gebruikelijke manier om het aantal stemmen in het algemeen bij te houden, is door het aantal stemmen in het postdocument te houden en het atomair bij te werken wanneer een nieuwe waarde naar de stemmenarray wordt gepusht.

Aangezien het een enkele update is, bent u er zeker van dat de telling overeenkomt met het aantal elementen in de array.

Als het aantal aggregaties vast is en de site erg druk is, zou je dit paradigma kunnen uitbreiden en extra tellers kunnen verhogen, zoals één voor maand, dag en uur, maar dat kan heel snel uit de hand lopen. Dus in plaats daarvan zou je het nieuwe Aggregation Framework kunnen gebruiken (beschikbaar in 2.1.2 dev release, zal in productie zijn in release 2.2. Het is eenvoudiger te gebruiken dan Map/Reduce en het stelt je in staat om de berekeningen die je wilt heel eenvoudig uit te voeren, vooral als je ervoor zorgt dat je je stemdata opslaat zoals ISODate()-type.

Typische pijplijn voor aggregatiequery's voor de beste stemmentrekkers deze maand kan er ongeveer zo uitzien:

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}
] );

Dit beperkt de invoer naar de pijplijn tot berichten die stemmen hebben door stemdatums te matchen met de maand die u aan het tellen bent, "ontwikkelt" de array om één document per stem te krijgen en voert vervolgens een "groeperen op" equivalent uit waarbij alle stemmen voor elke titel worden samengevat (Ik neem aan dat de titel uniek is). Het sorteert vervolgens aflopend op aantal stemmen en beperkt de uitvoer tot de eerste tien.

Je hebt ook de mogelijkheid om stemmen per dag (bijvoorbeeld) voor die maand te verzamelen om te zien op welke dagen het meest actief is om te stemmen:

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}
] );


  1. MapReduce met MongoDB echt, erg traag (30 uur versus 20 minuten in MySQL voor een vergelijkbare database)

  2. Laadt de MongoDB GetCollection-methode de hele verzameling in RAM of een referentie? C#

  3. Verbinding maken met Redis in Docker Container vanaf hostcomputer

  4. Waar is de NullPointer-uitzondering precies?