Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore:statistic canteen views #260

Merged
merged 21 commits into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
5193b9f
migrated cafeteria statistics to a view
CommanderStorm Oct 15, 2023
6ffe6b4
migrated DishRating
CommanderStorm Oct 15, 2023
83099a9
migrated dish_rating_tag_average
CommanderStorm Oct 15, 2023
cbfd6f8
migrated ...rating_tag_average
CommanderStorm Oct 15, 2023
9fe80ea
cleanup
CommanderStorm Oct 15, 2023
f888dd7
migrated dish_name_tag_average
CommanderStorm Oct 15, 2023
1527f10
removed the AverageRatingComputation cron job
CommanderStorm Oct 15, 2023
be7d097
fixed a part of the crontab I missed
CommanderStorm Oct 15, 2023
de38a1c
Merge branch 'main' into chore/statistics-views
CommanderStorm Oct 15, 2023
9ff7f2c
rebase
CommanderStorm Oct 15, 2023
26ed7c7
Merge branch 'main' into chore/statistics-views
CommanderStorm Oct 16, 2023
1c2a44e
Merge branch 'main' into chore/statistics-views
CommanderStorm Oct 21, 2023
abf0ce5
fixed the migration not being added to the list of migrations
CommanderStorm Oct 21, 2023
99be6a8
Fixed migrating the crontabs migrating the wrong way around
CommanderStorm Oct 23, 2023
84a6995
Merge branch 'main' into chore/statistics-views
CommanderStorm Oct 23, 2023
628f288
Merge branch 'main' into chore/statistics-views
CommanderStorm Oct 26, 2023
5af3b5b
remvoed the views from auto migrations
CommanderStorm Oct 26, 2023
a10f666
Merge branch 'main' into chore/statistics-views
CommanderStorm Oct 30, 2023
a8b09f2
Merge branch 'main' into chore/statistics-views
CommanderStorm Jan 2, 2024
e0becb9
Merge branch 'main' into chore/statistics-views
CommanderStorm Jan 2, 2024
44d5e36
linting fix
CommanderStorm Jan 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions server/api/tumdev/campus_backend.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions server/api/tumdev/campus_backend.proto
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ service Campus {
};
}

// Allows to query ratings for a specific dish in a specific cafeteria.
rpc GetDishRatings(GetDishRatingsRequest) returns (GetDishRatingsReply) {
option (google.api.http) = {
post: "/dish/rating/get",
Expand Down Expand Up @@ -295,10 +296,15 @@ message GetDishRatingsRequest {
}

message GetDishRatingsReply {
// a number of actual ratings
repeated SingleRatingReply rating = 1;
// average rating for all dish rating tags which were used to rate this dish in this cafeteria
double avg = 2;
// std of all dish rating tags which were used to rate this dish in this cafeteria
double std = 3;
// minimum of all dish rating tags which were used to rate this dish in this cafeteria
int32 min = 4;
// maximum of all dish rating tags which were used to rate this dish in this cafeteria
int32 max = 5;
repeated RatingTagResult rating_tags = 6;
repeated RatingTagResult name_tags = 7;
Expand Down
16 changes: 11 additions & 5 deletions server/api/tumdev/campus_backend.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@
},
"/dish/rating/get": {
"post": {
"summary": "Allows to query ratings for a specific dish in a specific cafeteria.",
"operationId": "Campus_GetDishRatings",
"responses": {
"200": {
Expand Down Expand Up @@ -1119,23 +1120,28 @@
"items": {
"type": "object",
"$ref": "#/definitions/apiSingleRatingReply"
}
},
"title": "a number of actual ratings"
},
"avg": {
"type": "number",
"format": "double"
"format": "double",
"title": "average rating for all dish rating tags which were used to rate this dish in this cafeteria"
},
"std": {
"type": "number",
"format": "double"
"format": "double",
"title": "std of all dish rating tags which were used to rate this dish in this cafeteria"
},
"min": {
"type": "integer",
"format": "int32"
"format": "int32",
"title": "minimum of all dish rating tags which were used to rate this dish in this cafeteria"
},
"max": {
"type": "integer",
"format": "int32"
"format": "int32",
"title": "maximum of all dish rating tags which were used to rate this dish in this cafeteria"
},
"ratingTags": {
"type": "array",
Expand Down
2 changes: 2 additions & 0 deletions server/api/tumdev/campus_backend_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

108 changes: 39 additions & 69 deletions server/backend/cafeteria.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,43 +34,34 @@ const (
NAME ModelType = 3
)

// GetCafeteriaRatings RPC Endpoint
// ListCanteenRatings RPC Endpoint
// Allows to query ratings for a specific cafeteria.
// It returns the average rating, max/min rating as well as a number of actual ratings and the average ratings for
// all cafeteria rating tags which were used to rate this cafeteria.
// The parameter limit defines how many actual ratings should be returned.
// The optional parameters from and to can define an interval in which the queried ratings have been stored.
// If these aren't specified, the newest ratings will be returned as the default
func (s *CampusServer) GetCafeteriaRatings(ctx context.Context, input *pb.ListCanteenRatingsRequest) (*pb.ListCanteenRatingsReply, error) {
var result model.CafeteriaRatingAverage //get the average rating for this specific cafeteria
func (s *CampusServer) ListCanteenRatings(ctx context.Context, input *pb.ListCanteenRatingsRequest) (*pb.ListCanteenRatingsReply, error) {
var statsForCanteen model.CafeteriaRatingStatistic
tx := s.db.WithContext(ctx)
cafeteriaId := getIDForCafeteriaName(input.CanteenId, tx)

res := tx.First(&result, "cafeteriaId = ?", cafeteriaId)
if res.Error != nil {
log.WithError(res.Error).Error("Error while querying the cafeteria with Id ", cafeteriaId)
return nil, status.Error(codes.Internal, "This cafeteria has not yet been rated.")
}
if res.RowsAffected > 0 {
ratings := queryLastCafeteriaRatingsWithLimit(input, cafeteriaId, tx)
cafeteriaTags := queryTags(cafeteriaId, -1, CAFETERIA, tx)

return &pb.ListCanteenRatingsReply{
Avg: result.Average,
Std: result.Std,
Min: result.Min,
Max: result.Max,
Rating: ratings,
RatingTags: cafeteriaTags,
}, nil
} else {
return &pb.ListCanteenRatingsReply{
Avg: -1,
Std: -1,
Min: -1,
Max: -1,
}, nil
err := tx.First(&statsForCanteen, "cafeteriaId = ?", cafeteriaId).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, status.Error(codes.NotFound, "No cafeteria with this Id found.")
}
if err != nil {
log.WithError(err).Error("Error while querying the cafeteria with Id ", cafeteriaId)
return nil, status.Error(codes.Internal, "could not query the cafeteria with the given Id")
}

return &pb.ListCanteenRatingsReply{
Avg: statsForCanteen.Average,
Std: statsForCanteen.Std,
Min: statsForCanteen.Min,
Max: statsForCanteen.Max,
Rating: queryLastCafeteriaRatingsWithLimit(input, cafeteriaId, tx),
RatingTags: queryTags(cafeteriaId, -1, CAFETERIA, tx),
}, nil
}

// queryLastCafeteriaRatingsWithLimit
Expand Down Expand Up @@ -99,8 +90,7 @@ func queryLastCafeteriaRatingsWithLimit(input *pb.ListCanteenRatingsRequest, caf
} else {
to = input.To.AsTime()
}
err = tx.
Order("timestamp desc, cafeteriaRating desc").
err = tx.Order("timestamp desc, cafeteriaRating desc").
Limit(limit).
Find(&ratings, "cafeteriaID = ? AND timestamp < ? AND timestamp > ?", cafeteriaID, to, from).Error
} else {
Expand Down Expand Up @@ -129,51 +119,31 @@ func queryLastCafeteriaRatingsWithLimit(input *pb.ListCanteenRatingsRequest, caf
}
}

// GetDishRatings RPC Endpoint
// Allows to query ratings for a specific dish in a specific cafeteria.
// It returns the average rating, max/min rating as well as a number of actual ratings and the average ratings for
// all dish rating tags which were used to rate this dish in this cafeteria. Additionally, the average, max/min are
// returned for every name tag which matches the name of the dish.
// The parameter limit defines how many actual ratings should be returned.
// The optional parameters from and to can define a interval in which the queried ratings have been stored.
// If these aren't specified, the newest ratings will be returned as the default
func (s *CampusServer) GetDishRatings(ctx context.Context, input *pb.GetDishRatingsRequest) (*pb.GetDishRatingsReply, error) {
var result model.DishRatingAverage //get the average rating for this specific dish
tx := s.db.WithContext(ctx)
cafeteriaID := getIDForCafeteriaName(input.CanteenId, tx)
dishID := getIDForDishName(input.Dish, cafeteriaID, tx)

res := tx.First(&result, "cafeteriaID = ? AND dishID = ?", cafeteriaID, dishID)

if res.Error != nil {
var statsForDish model.DishRatingStatistic
err := tx.First(&statsForDish, "cafeteriaID = ? AND dishID = ?", cafeteriaID, dishID).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, status.Error(codes.NotFound, "No cafeteria with this Id found.")
}
if err != nil {
fields := log.Fields{"dishID": dishID, "cafeteriaID": cafeteriaID}
log.WithError(res.Error).WithFields(fields).Error("Error while querying the average ratings")
log.WithError(err).WithFields(fields).Error("Error while querying the average ratings")
return nil, status.Error(codes.Internal, "This dish has not yet been rated.")
}

if res.RowsAffected > 0 {
ratings := queryLastDishRatingsWithLimit(input, cafeteriaID, dishID, tx)
dishTags := queryTags(cafeteriaID, dishID, DISH, tx)
nameTags := queryTags(cafeteriaID, dishID, NAME, tx)

return &pb.GetDishRatingsReply{
Avg: result.Average,
Std: result.Std,
Min: result.Min,
Max: result.Max,
Rating: ratings,
RatingTags: dishTags,
NameTags: nameTags,
}, nil
} else {
return &pb.GetDishRatingsReply{
Avg: -1,
Min: -1,
Max: -1,
Std: -1,
}, nil
}

return &pb.GetDishRatingsReply{
Avg: statsForDish.Average,
Std: statsForDish.Std,
Min: statsForDish.Min,
Max: statsForDish.Max,
Rating: queryLastDishRatingsWithLimit(input, cafeteriaID, dishID, tx),
RatingTags: queryTags(cafeteriaID, dishID, DISH, tx),
NameTags: queryTags(cafeteriaID, dishID, NAME, tx),
}, nil
}

// queryLastDishRatingsWithLimit
Expand Down Expand Up @@ -273,14 +243,14 @@ func queryTags(cafeteriaID int32, dishID int32, ratingType ModelType, tx *gorm.D
var err error
if ratingType == DISH {
err = tx.Table("dish_rating_tag_option options").
Joins("JOIN dish_rating_tag_average results ON options.dishRatingTagOption = results.tagID").
Joins("JOIN dish_rating_tag_statistics results ON options.dishRatingTagOption = results.tagID").
Select("options.dishRatingTagOption as tagId, results.average as avg, "+
"results.min as min, results.max as max, results.std as std").
Where("results.cafeteriaID = ? AND results.dishID = ?", cafeteriaID, dishID).
Scan(&results).Error
} else if ratingType == CAFETERIA {
err = tx.Table("cafeteria_rating_tag_option options").
Joins("JOIN cafeteria_rating_tag_average results ON options.cafeteriaRatingTagOption = results.tagID").
Joins("JOIN cafeteria_rating_tag_statistics results ON options.cafeteriaRatingTagOption = results.tagID").
Select("options.cafeteriaRatingTagOption as tagId, results.average as avg, "+
"results.min as min, results.max as max, results.std as std").
Where("results.cafeteriaID = ?", cafeteriaID).
Expand All @@ -289,7 +259,7 @@ func queryTags(cafeteriaID int32, dishID int32, ratingType ModelType, tx *gorm.D
err = tx.Table("dish_to_dish_name_tag mapping").
Where("mapping.dishID = ?", dishID).
Select("mapping.nameTagID as tag").
Joins("JOIN dish_name_tag_average results ON mapping.nameTagID = results.tagID").
Joins("JOIN dish_name_tag_statistic results ON mapping.nameTagID = results.tagID").
Joins("JOIN dish_name_tag_option options ON mapping.nameTagID = options.dishNameTagOption").
Select("mapping.nameTagID as tagId, results.average as avg, " +
"results.min as min, results.max as max, results.std as std").
Expand Down
117 changes: 0 additions & 117 deletions server/backend/cron/average_rating_computation.go

This file was deleted.

Loading
Loading