optimize get index trends info logic

pull/393/head
Michael Li 9 months ago
parent e076988242
commit 9ca38cb4b5
No known key found for this signature in database

@ -40,6 +40,7 @@ const (
TablePostStar = "post_star" TablePostStar = "post_star"
TableTag = "tag" TableTag = "tag"
TableUser = "user" TableUser = "user"
TableUserRelation = "user_relation"
TableUserMetric = "user_metric" TableUserMetric = "user_metric"
TableWalletRecharge = "wallet_recharge" TableWalletRecharge = "wallet_recharge"
TableWalletStatement = "wallet_statement" TableWalletStatement = "wallet_statement"

@ -368,6 +368,7 @@ func (s *databaseConf) TableNames() (res TableNameMap) {
TablePostStar, TablePostStar,
TableTag, TableTag,
TableUser, TableUser,
TableUserRelation,
TableUserMetric, TableUserMetric,
TableWalletRecharge, TableWalletRecharge,
TableWalletStatement, TableWalletStatement,

@ -4,9 +4,27 @@
package cs package cs
import "github.com/rocboss/paopao-ce/pkg/types"
type TrendsItem struct { type TrendsItem struct {
Username string `json:"username"` Username string `json:"username"`
Nickname string `json:"nickname"` Nickname string `json:"nickname"`
Avatar string `json:"avatar"` Avatar string `json:"avatar"`
IsFresh bool `json:"is_fresh" gorm:"-"` IsFresh bool `json:"is_fresh" gorm:"-"`
} }
func DistinctTrends(items []*TrendsItem) []*TrendsItem {
if len(items) == 0 {
return items
}
res := make([]*TrendsItem, 0, len(items))
set := make(map[string]types.Empty, len(items))
for _, item := range items {
if _, exist := set[item.Username]; exist {
continue
}
res = append(res, item)
set[item.Username] = types.Empty{}
}
return res
}

@ -32,6 +32,7 @@ var (
_postStar_ string _postStar_ string
_tag_ string _tag_ string
_user_ string _user_ string
_userRelation_ string
_userMetric_ string _userMetric_ string
_walletRecharge_ string _walletRecharge_ string
_walletStatement_ string _walletStatement_ string
@ -61,6 +62,7 @@ func initTableName() {
_postStar_ = m[conf.TablePostStar] _postStar_ = m[conf.TablePostStar]
_tag_ = m[conf.TableTag] _tag_ = m[conf.TableTag]
_user_ = m[conf.TableUser] _user_ = m[conf.TableUser]
_userRelation_ = m[conf.TableUserRelation]
_userMetric_ = m[conf.TableUserMetric] _userMetric_ = m[conf.TableUserMetric]
_walletRecharge_ = m[conf.TableWalletRecharge] _walletRecharge_ = m[conf.TableWalletRecharge]
_walletStatement_ = m[conf.TableWalletStatement] _walletStatement_ = m[conf.TableWalletStatement]

@ -18,16 +18,18 @@ type trendsSrvA struct {
func (s *trendsSrvA) GetIndexTrends(userId int64, limit int, offset int) (res []*cs.TrendsItem, total int64, err error) { func (s *trendsSrvA) GetIndexTrends(userId int64, limit int, offset int) (res []*cs.TrendsItem, total int64, err error) {
db := s.db.Table(_user_). db := s.db.Table(_user_).
Joins(fmt.Sprintf("JOIN %s c ON c.friend_id=%s.id AND c.user_id=? AND c.status=2 AND c.is_del=0", _contact_, _user_), userId). Joins(fmt.Sprintf("JOIN %s r ON r.he_uid=%s.id", _userRelation_, _user_)).
Joins(fmt.Sprintf("JOIN %s m ON c.friend_id=m.user_id AND m.tweets_count>0 AND m.is_del=0", _userMetric_)). Joins(fmt.Sprintf("JOIN %s m ON r.he_uid=m.user_id", _userMetric_)).
Where(fmt.Sprintf("%s.is_del=0", _user_)) Where("r.user_id=? AND m.tweets_count>0 AND m.is_del=0", userId)
if err = db.Count(&total).Error; err != nil || total == 0 { if err = db.Count(&total).Error; err != nil || total == 0 {
return return
} }
if offset >= 0 && limit > 0 { if offset >= 0 && limit > 0 {
db = db.Limit(limit).Offset(offset) db = db.Limit(limit).Offset(offset)
} }
err = db.Find(&res).Error if err = db.Order("r.style ASC").Select("username", "nickname", "avatar").Find(&res).Error; err == nil {
res = cs.DistinctTrends(res)
}
return return
} }

@ -41,6 +41,10 @@ const (
const ( const (
_trendsActionCreateTweet uint8 = iota _trendsActionCreateTweet uint8 = iota
_trendsActionDeleteTweet _trendsActionDeleteTweet
_trendsActionFollowUser
_trendsActionUnfollowUser
_trendsActionAddFriend
_trendsActionDeleteFriend
) )
type cacheUnreadMsgEvent struct { type cacheUnreadMsgEvent struct {
@ -75,18 +79,18 @@ type messageActionEvent struct {
type trendsActionEvent struct { type trendsActionEvent struct {
event.UnimplementedEvent event.UnimplementedEvent
ac core.AppCache ac core.AppCache
ds core.DataService ds core.DataService
action uint8 action uint8
userId int64 userIds []int64
} }
func onTrendsActionEvent(action uint8, userId int64) { func onTrendsActionEvent(action uint8, userIds ...int64) {
events.OnEvent(&trendsActionEvent{ events.OnEvent(&trendsActionEvent{
ac: _ac, ac: _ac,
ds: _ds, ds: _ds,
action: action, action: action,
userId: userId, userIds: userIds,
}) })
} }
@ -246,23 +250,39 @@ func (e *trendsActionEvent) Action() (err error) {
switch e.action { switch e.action {
case _trendsActionCreateTweet: case _trendsActionCreateTweet:
logrus.Debug("trigger trendsActionEvent by create tweet ") logrus.Debug("trigger trendsActionEvent by create tweet ")
e.ds.UpdateUserMetric(e.userId, cs.MetricActionCreateTweet) e.updateUserMetric(cs.MetricActionCreateTweet)
goto ExpireTrends e.expireFriendTrends()
case _trendsActionDeleteTweet: case _trendsActionDeleteTweet:
logrus.Debug("trigger trendsActionEvent by delete tweet ") logrus.Debug("trigger trendsActionEvent by delete tweet ")
e.ds.UpdateUserMetric(e.userId, cs.MetricActionDeleteTweet) e.updateUserMetric(cs.MetricActionDeleteTweet)
goto ExpireTrends e.expireFriendTrends()
case _trendsActionAddFriend, _trendsActionDeleteFriend,
_trendsActionFollowUser, _trendsActionUnfollowUser:
e.expireMyTrends()
default: default:
// nothing // nothing
goto JustReturn
} }
ExpireTrends: return
if friendIds, err := e.ds.MyFriendIds(e.userId); err == nil { }
for _, id := range friendIds {
e.ac.DelAny(fmt.Sprintf("%s%d:*", conf.PrefixIdxTrends, id)) func (e *trendsActionEvent) updateUserMetric(action uint8) {
for _, userId := range e.userIds {
e.ds.UpdateUserMetric(userId, action)
}
}
func (e *trendsActionEvent) expireFriendTrends() {
for _, userId := range e.userIds {
if friendIds, err := e.ds.MyFriendIds(userId); err == nil {
for _, id := range friendIds {
e.ac.DelAny(fmt.Sprintf("%s%d:*", conf.PrefixIdxTrends, id))
}
} }
return err
} }
JustReturn: }
return
func (e *trendsActionEvent) expireMyTrends() {
for _, userId := range e.userIds {
e.ac.DelAny(fmt.Sprintf("%s%d:*", conf.PrefixIdxTrends, userId))
}
} }

@ -90,6 +90,7 @@ func (s *followshipSrv) UnfollowUser(r *web.UnfollowUserReq) mir.Error {
cache.OnCacheMyFollowIdsEvent(s.Ds, r.User.ID) cache.OnCacheMyFollowIdsEvent(s.Ds, r.User.ID)
cache.OnExpireIndexTweetEvent(r.User.ID) cache.OnExpireIndexTweetEvent(r.User.ID)
onMessageActionEvent(_messageActionFollow, r.User.ID) onMessageActionEvent(_messageActionFollow, r.User.ID)
onTrendsActionEvent(_trendsActionUnfollowUser, r.User.ID)
return nil return nil
} }
@ -108,6 +109,7 @@ func (s *followshipSrv) FollowUser(r *web.FollowUserReq) mir.Error {
cache.OnCacheMyFollowIdsEvent(s.Ds, r.User.ID) cache.OnCacheMyFollowIdsEvent(s.Ds, r.User.ID)
cache.OnExpireIndexTweetEvent(r.User.ID) cache.OnExpireIndexTweetEvent(r.User.ID)
onMessageActionEvent(_messageActionFollow, r.User.ID) onMessageActionEvent(_messageActionFollow, r.User.ID)
onTrendsActionEvent(_trendsActionFollowUser, r.User.ID)
return nil return nil
} }

@ -57,6 +57,7 @@ func (s *friendshipSrv) DeleteFriend(req *web.DeleteFriendReq) mir.Error {
} }
// 触发用户关系缓存更新事件 // 触发用户关系缓存更新事件
// cache.OnCacheMyFriendIdsEvent(s.Ds, req.User.ID, req.UserId) // cache.OnCacheMyFriendIdsEvent(s.Ds, req.User.ID, req.UserId)
onTrendsActionEvent(_trendsActionDeleteFriend, req.User.ID, req.UserId)
return nil return nil
} }
@ -93,6 +94,7 @@ func (s *friendshipSrv) AddFriend(req *web.AddFriendReq) mir.Error {
} }
// 触发用户关系缓存更新事件 // 触发用户关系缓存更新事件
// cache.OnCacheMyFriendIdsEvent(s.Ds, req.User.ID, req.UserId) // cache.OnCacheMyFriendIdsEvent(s.Ds, req.User.ID, req.UserId)
onTrendsActionEvent(_trendsActionAddFriend, req.User.ID, req.UserId)
return nil return nil
} }

@ -1,5 +1,2 @@
DROP VIEW IF EXISTS p_post_by_media; DROP VIEW IF EXISTS p_post_by_media;
DROP VIEW IF EXISTS p_post_by_comment; DROP VIEW IF EXISTS p_post_by_comment;

@ -0,0 +1 @@
DROP VIEW IF EXISTS p_user_relation;

@ -0,0 +1,6 @@
CREATE VIEW p_user_relation AS
SELECT user_id, friend_id he_uid, 5 AS style
FROM p_contact WHERE status=2 AND is_del=0
UNION
SELECT user_id, follow_id he_uid, 10 AS style
FROM p_following WHERE is_del=0;

@ -0,0 +1 @@
DROP VIEW IF EXISTS p_user_relation;

@ -0,0 +1,6 @@
CREATE VIEW p_user_relation AS
SELECT user_id, friend_id he_uid, 5 AS style
FROM p_contact WHERE status=2 AND is_del=0
UNION
SELECT user_id, follow_id he_uid, 10 AS style
FROM p_following WHERE is_del=0;

@ -0,0 +1 @@
DROP VIEW IF EXISTS p_user_relation;

@ -0,0 +1,6 @@
CREATE VIEW p_user_relation AS
SELECT user_id, friend_id he_uid, 5 AS style
FROM p_contact WHERE status=2 AND is_del=0
UNION
SELECT user_id, follow_id he_uid, 10 AS style
FROM p_following WHERE is_del=0;

@ -503,4 +503,12 @@ FROM
WHERE WHERE
P.is_del = 0; P.is_del = 0;
DROP VIEW IF EXISTS p_user_relation;
CREATE VIEW p_user_relation AS
SELECT user_id, friend_id he_uid, 5 AS style
FROM p_contact WHERE status=2 AND is_del=0
UNION
SELECT user_id, follow_id he_uid, 10 AS style
FROM p_following WHERE is_del=0;
SET FOREIGN_KEY_CHECKS = 1; SET FOREIGN_KEY_CHECKS = 1;

@ -415,3 +415,11 @@ FROM
C JOIN p_post P ON C.post_id = P.ID C JOIN p_post P ON C.post_id = P.ID
WHERE WHERE
P.is_del = 0; P.is_del = 0;
DROP VIEW IF EXISTS p_user_relation;
CREATE VIEW p_user_relation AS
SELECT user_id, friend_id he_uid, 5 AS style
FROM p_contact WHERE status=2 AND is_del=0
UNION
SELECT user_id, follow_id he_uid, 10 AS style
FROM p_following WHERE is_del=0;

@ -457,6 +457,14 @@ FROM
WHERE WHERE
P.is_del = 0; P.is_del = 0;
DROP VIEW IF EXISTS p_user_relation;
CREATE VIEW p_user_relation AS
SELECT user_id, friend_id he_uid, 5 AS style
FROM p_contact WHERE status=2 AND is_del=0
UNION
SELECT user_id, follow_id he_uid, 10 AS style
FROM p_following WHERE is_del=0;
-- ---------------------------- -- ----------------------------
-- Indexes structure for table p_attachment -- Indexes structure for table p_attachment
-- ---------------------------- -- ----------------------------

Loading…
Cancel
Save