2017-08-17 3 views
1

Im construire une application qui aura une fonctionnalité qui vous permet de noter les utilisateurs sur une échelle de 1-5. Je l'ai déjà décidé que je vais utiliser une moyenne pondérée comme ceci:Conception de base de données système 5 étoiles rating

Sum of (weight * number of reviews at that weight)/total number of reviews

Im ayant du mal à trouver comment stocker ces données en utilisant firebase, puisque j'ai besoin de cette valeur de notation pour initialiser un objet User . J'ai pensé à stocker chaque note comme un dictionnaire où la clé est id de l'utilisateur laissant examen, et la valeur est la note réelle. Puis, après que je vais chercher l'utilisateur de base de données et ont besoin d'initialiser User je fais ce qui suit:

// keep track of amount of each rating. 
    var oneStars = 0 
    var twoStars = 0 
    var threeStars = 0 
    var fourStars = 0 
    var fiveStars = 0 

    // iterate through dictionary of ratings where key is unique Id, and value is star rating. 
    for (key, value) in ratings { 
     switch value { 
     case 1: oneStars += 1 
     case 2: twoStars += 1 
     case 3: threeStars += 1 
     case 4: fourStars += 1 
     case 5: fiveStars += 1 
     } 
    } 

    let weightedSum = (
     (5 * fiveStars) + 
     (4 * fourStars) + 
     (3 * threeStars) + 
     (2 * twoStars) + 
     (1 * oneStars) 
    ) 

    let reviewsSum = oneStars + twoStars + threeStars + fourStars + fiveStars 

    let rating = weightedSum/reviewsSum 

    let user = User(name: "john doe", rating: rating) 

Est-ce la meilleure façon de stocker les notes, et faire le calcul réel pour initialiser l'objet, ou est-il une conception plus efficace? Merci.

Répondre

1

Vous avez probablement besoin de stocker la note de chaque utilisateur, donc c'est bien de stocker les notes de cette manière.

En ce qui concerne le calcul de la note finale, voici une meilleure mise en œuvre:

var count = 0 
var rating = 0 

for (key, value) in ratings { 
    count += 1 
    rating += value 
} 

rating /= count 

let user = User(name: "john doe", rating: rating) 

Un autre algorithme qui peut traiter avec une énorme quantité de sorcière notes pourrait conduire à overflow:

var count = 0 
var rating = 0 

for (key, value) in ratings { 
    count += 1 
    rating += (value - rating)/count 
} 

let user = User(name: "john doe", rating: rating) 

Le deuxième algorithme fonctionne très bien si vous recalculez les cotes du coté serveur chaque fois qu'un nouvel utilisateur évalue (dans le cas où vous avez un nombre important d'utilisateurs accédant à ces cotes, et aussi d'énormes quantités de cotes, mieux vaut le calculer côté serveur).