sql >> Database teknologi >  >> NoSQL >> MongoDB

Skema for brugerbedømmelser - nøgle/værdi-DB

Først og fremmest er 'Ordbog i brugerklasse' ikke en god idé. hvorfor? Tilføjelse af et ekstra satsobjekt kræver, at du skubber et nyt element til arrayet, hvilket betyder, at det gamle element vil blive fjernet, og denne indsættelse kaldes "flytning af et dokument ". Flytning af dokumenter er langsom, og MongoDB er ikke så god til at genbruge tom plads, så flytning af dokumenter kan resultere i store dele af tomme datafiler (noget tekst i 'MongoDB The Definitive Guide'-bogen).

Hvad er så den rigtige løsning:antag, at du har en samling ved navn Blogs, og ønsker at implementere en vurderingsløsning til dine blogindlæg, og derudover holde styr på hver brugerbaseret prisoperation.

Skemaet for et blogdokument ville være sådan:

{
   _id : ....,
   title: ....,
   ....
   rateCount : 0,
   rateValue : 0,
   rateAverage: 0
}

Du har brug for en anden samling (priser) med dette dokumentskema:

{
    _id: ....,
    userId: ....,
    postId:....,
    value: ..., //1 to 5
    date:....   
}

Og du skal definere et korrekt indeks for det:

db.Rates.ensureIndex({userId : 1, postId : 1})// very useful. it will result in a much faster search operation in case you want to check if a user has rated the post previously

Når en bruger vil bedømme, skal du først tjekke, om brugeren har bedømt indlægget eller ej. antag, at brugeren er 'user1' , ville forespørgslen derefter være

var ratedBefore = db.Rates.find({userId : 'user1', postId : 'post1'}).count()

Og baseret på ratedBefore , hvis !ratedBefore indsæt derefter et nyt takstdokument til Prisindsamling og opdater blogstatus, ellers har brugeren ikke lov til at vurdere

if(!ratedBefore)
{
    var postId = 'post1'; // this id sould be passed before by client driver
    var userId = 'user1'; // this id sould be passed before by client driver
    var rateValue = 1; // to 5
    var rate = 
    {       
       userId: userId,
       postId: postId,
       value: rateValue,
       date:new Date()  
    };

    db.Rates.insert(rate);
    db.Blog.update({"_id" : postId}, {$inc : {'rateCount' : 1, 'rateValue' : rateValue}});
}

Hvad sker der så med rateAverage ?Jeg anbefaler kraftigt at beregne det baseret på rateCount og rateValue på klientsiden er det nemt at opdatere rateAverage med mongoquery , men du bør ikke gøre det. hvorfor? Det enkle svar er:dette er en meget nem opgave for klienten at håndtere denne slags arbejde, og at sætte gennemsnit på hvert blogdokument kræver en unødvendig opdatering.

den gennemsnitlige forespørgsel ville blive beregnet som:

var blog = db.Blog.findOne({"_id" : "post1"});
var avg = blog.rateValue / blog.rateCount;
print(avg);

Med denne tilgang vil du få maksimal ydeevne med mongodb og du har styr på hver pris baseret på bruger, indlæg og dato.



  1. Redis cache vs brug af hukommelse direkte

  2. Få forfædre i MongoDb ved hjælp af træstruktur

  3. Hvordan opdaterer man et enkelt objekt med RESTHeart patch?

  4. Indlejret array $pull-forespørgsel ved hjælp af C# MongoDB-driver