【发布时间】:2019-04-19 03:50:26
【问题描述】:
我的数据库结构是这样的:
Restaurants
@-restaurantId_0
@-reviewId_1
-rating: 1
-user: uid_A
@-reviewId_2
-rating: 0.5
-user: uid_B
@-reviewId_3
-rating: 3
-user: uid_C
@-restaurantId_1
@-reviewId_4
-rating: 4
-user: uid_A
@-reviewId_5
-rating: 2.5
-user: uid_S
@-restaurantId_2
// ...
@-restaurantId_3
// ...
我有一个星级评分系统,每个用户都可以为餐厅评分。我记录了他们在该评论下留下的评分和他们的 uid。
当显示特定餐厅及其星级时,我需要从每条评论中获取所有评分(针对该餐厅),然后进行一些计算以确定餐厅的总评分:
allTheRatingsAddedUp / totatNumOfReviews
例如。在我上面的数据库结构中,带有 restaurantId_0 的餐厅有 3 条评论,所有评分加起来为 4.5,所以它会有 1.5星级 总评分(4.5 / 3)。
我可以使用以下方法以 2 种不同的方式获取此信息。在这两种方式中,我都必须遍历所有评论以获得所有评分的总和。正如您在下面看到的,要获得总和涉及很多代码。
有没有更有效的方法可以在不使用这么多代码的情况下实现所有评分的总和?
在这种情况下,事务块会更好地工作吗?据我了解,交易块会跟踪评分,因此即使用户正在查看 restaurantId_0 和 1.5 rating,如果其他 3 个用户留下高评分,交易块也会立即反映这一点,并且星级会改变(运行新计算后)
第一种方式
Database.database().reference()
.child("Restaurants")
.child("restaurantId_0")
.observeSingleEvent(of: .value, with: { (snapshot) in
if !snapshot.exists() {
return
}
let totatNumOfReviews = snapshot.childrenCount
var arrOfReviews = [ReviewModel]()
var allTheRatingsAddedUp = 0.0
guard let dictionaries = snapshot.value as? [String: Any] else { return }
var count = 0
dictionaries.forEach({ (key, value) in
guard let dict = value as? [String: Any] else { return }
var review = ReviewModel(dict: dict)
review.reviewId = key
let isContained = arrOfReviews.contains(where: { (containedReview) -> Bool in
return review.reviewId == containedReview.reviewId
})
if !isContained {
arrOfReviews.append(review)
allTheRatingsAddedUp += review.rating ?? 0
count += 1
if count == totatNumOfReviews {
// run calculations on: allTheRatingsAddedUp / totatNumOfReviews
}
}
})
})
第二种方式
Database.database().reference()
.child("Restaurants")
.child("restaurantId_0")
.observeSingleEvent(of: .value) { (snapshot) in
if !snapshot.exists() {
return
}
let totatNumOfReviews = snapshot.childrenCount
var arrOfReviews = [ReviewModel]()
var allTheRatingsAddedUp = 0.0
Database.database().reference()
.child("Restaurants")
.child("restaurantId_0")
.observe( .childAdded, with: { (snapshot) in
if let dict = snapshot.value as? [String: Any] {
let review = ReviewModel(dict: dict)
arrOfReviews.append(review)
allTheRatingsAddedUp += review.rating ?? 0
if arrOfReviews.count == totatNumOfReviews {
// run calculations on: allTheRatingsAddedUp / totatNumOfReviews
}
}
})
【问题讨论】:
标签: ios swift firebase firebase-realtime-database