refactor(web): 重构动物列表查询逻辑
- 优化了 prefer 模式下的查询流程,减少了冗余代码 - 重构了 getPreferCatsId 函数,增加了 skip 参数支持分页查询 - 修改了 Encounter 模型中的 EncounteredCats 方法,支持 DISTINCT 查询和分页 - 提高了查询效率,减少了数据库访问次数
This commit is contained in:
parent
e33f9a1801
commit
4d2f304ab7
@ -36,9 +36,10 @@ func (a *Animals) List(context *gin.Context) {
|
||||
|
||||
mode := context.GetString(consts.ValidatorPrefix + "mode")
|
||||
|
||||
var preferCatsId []int64
|
||||
// TAG prefer MODE 查询模式。
|
||||
var redis_preferCatsId []int64
|
||||
var key int64
|
||||
var animalsWithLike []model.AnimalWithLikeList
|
||||
if mode == consts.AnimalPreferMode {
|
||||
key = int64(context.GetFloat64(consts.ValidatorPrefix + "key"))
|
||||
|
||||
@ -51,35 +52,17 @@ func (a *Animals) List(context *gin.Context) {
|
||||
}
|
||||
|
||||
if len(redis_preferCatsId) == skip {
|
||||
preferCatsId, _ = getPreferCatsId(int(userId), int(num))
|
||||
redis_preferCatsId = append(redis_preferCatsId, preferCatsId...)
|
||||
preferCatsId, preferCats, _ := getPreferCatsId(int(userId), num, skip, attrs)
|
||||
if len(preferCatsId) > 0 {
|
||||
redis_preferCatsId = append(redis_preferCatsId, preferCatsId...)
|
||||
animalsWithLike = append(animalsWithLike, preferCats...)
|
||||
}
|
||||
|
||||
if _, err := redisClient.String(redisClient.Execute("lpush", key, redis_preferCatsId)); err != nil {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var animalsWithLike []model.AnimalWithLikeList
|
||||
if len(preferCatsId) > 0 {
|
||||
// 创建一个 map 来存储查询结果
|
||||
animalMap := make(map[int64]model.Animal, len(preferCatsId))
|
||||
|
||||
attrsSlice := query_handler.StringToStringArray(attrs)
|
||||
attrsSlice = append(attrsSlice, "id")
|
||||
animals := model.CreateAnimalFactory("").ShowByIDs(preferCatsId, attrsSlice...)
|
||||
|
||||
for _, v := range animals {
|
||||
animalMap[v.Id] = v
|
||||
}
|
||||
|
||||
// 根据 preferCatsId 的顺序构建最终结果列表
|
||||
for _, id := range preferCatsId {
|
||||
if animal, ok := animalMap[id]; ok {
|
||||
animalsWithLike = append(animalsWithLike, model.AnimalWithLikeList{Animal: animal})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 计算还需要多少动物
|
||||
num -= len(animalsWithLike)
|
||||
skip = max(0, skip-len(redis_preferCatsId))
|
||||
@ -100,25 +83,30 @@ func (a *Animals) List(context *gin.Context) {
|
||||
}
|
||||
|
||||
// UPDATE 就先简单一些,主要就依靠 encounter - animal_id 来获取一个目标。
|
||||
func getPreferCatsId(userId, num int) ([]int64, error) {
|
||||
// STAGE check 一下 key 是否存在。
|
||||
// if key != "" {
|
||||
// redisClient := redis_factory.GetOneRedisClient()
|
||||
// defer redisClient.ReleaseOneRedisClient()
|
||||
// if res, err := redisClient.Bool(redisClient.Execute("get", key)); err != nil {
|
||||
// if res { // 如果 redis 返回的是 1,则代表 prefer 已经耗尽了。
|
||||
// return nil, err
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// STAGE - 1 模块一,无视条件,获取路遇过的 id 列表;先获取 ID,然后再去查询细节信息。
|
||||
encounteredCats, err := model.CreateEncounterFactory("").EncounteredCats(userId, num)
|
||||
func getPreferCatsId(userId, num, skip int, attrs string) (ids []int64, list []model.AnimalWithLikeList, err error) {
|
||||
// STAGE - 1 模块一,无视过滤条件,获取路遇“过”的 id 列表;先获取 ID,然后再去查询细节信息。
|
||||
ids, err = model.CreateEncounterFactory("").EncounteredCats(userId, num, skip)
|
||||
|
||||
if err != nil {
|
||||
// variable.ZapLog.Error("获取用户浏览记录失败", Zap.Error(err))
|
||||
return encounteredCats, err
|
||||
if err == nil && len(ids) > 0 {
|
||||
attrsSlice := query_handler.StringToStringArray(attrs)
|
||||
attrsSlice = append(attrsSlice, "id")
|
||||
|
||||
animalMap := make(map[int64]model.Animal, len(ids))
|
||||
animals := model.CreateAnimalFactory("").ShowByIDs(ids, attrsSlice...)
|
||||
|
||||
for _, v := range animals {
|
||||
animalMap[v.Id] = v
|
||||
}
|
||||
|
||||
// 根据 preferCatsId 的顺序重构最终结果列表
|
||||
for _, id := range ids {
|
||||
if animal, ok := animalMap[id]; ok {
|
||||
list = append(list, model.AnimalWithLikeList{Animal: animal})
|
||||
}
|
||||
}
|
||||
}
|
||||
return encounteredCats, nil
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// v0.1
|
||||
|
@ -157,21 +157,6 @@ func (e *Encounter) ShowByID(id int64) (temp *Encounter, err error) {
|
||||
return
|
||||
}
|
||||
return
|
||||
// // 2. search user data
|
||||
// user := UsersModel{BaseModel: BaseModel{Id: encounter.UsersModelId}}
|
||||
// if err := user.Select("user_name", "user_avatar").First(&user).Error; err != nil {
|
||||
// return
|
||||
// }
|
||||
|
||||
// // 3. search animals data
|
||||
// animals_id := query_handler.StringToint64Array(encounter.AnimalsId)
|
||||
// var animals []Animal
|
||||
// if err := e.Model(&animals).Select("id", "avatar", "name").Where("id in (?)", animals_id).Find(&animals).Error; err != nil {
|
||||
// return
|
||||
// }
|
||||
|
||||
// // TODO 4. 然后整合
|
||||
// return
|
||||
}
|
||||
|
||||
func (e *Encounter) ShowByIDs(ids []int64, attrs ...string) (temp []Encounter) {
|
||||
@ -189,30 +174,28 @@ func (e *Encounter) ShowByIDs(ids []int64, attrs ...string) (temp []Encounter) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 过去 1 个月,发送过路遇表的 ids,同时去重。
|
||||
* @description: 过去 1 个月,发送过路遇表的 ids,同时 SQL 去重。
|
||||
* @param {*} user_id
|
||||
* @param {int} num
|
||||
* @param {int} num 限制查询的数量;
|
||||
* @return {*}
|
||||
*/
|
||||
func (e *Encounter) EncounteredCats(user_id, num int) ([]int64, error) {
|
||||
sql := `SELECT eal.animal_id
|
||||
func (e *Encounter) EncounteredCats(user_id, num, skip int) ([]int64, error) {
|
||||
sql := `SELECT DISTINCT eal.animal_id
|
||||
FROM encounter_animal_links eal
|
||||
JOIN encounters e
|
||||
ON e.id = eal.encounter_id AND e.user_id = ?
|
||||
WHERE e.updated_at >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH)
|
||||
ORDER BY e.updated_at DESC
|
||||
LIMIT ?`
|
||||
WHERE e.updated_at >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH)
|
||||
ORDER BY e.updated_at DESC
|
||||
LIMIT ? OFFSET ?`
|
||||
|
||||
rows, err := e.Raw(sql, user_id, num).Rows()
|
||||
rows, err := e.Raw(sql, user_id, num, skip).Rows()
|
||||
if err != nil {
|
||||
log.Println("查询失败:", err)
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
// Scan 同时去重。
|
||||
var temp []int64
|
||||
seen := make(map[int64]bool)
|
||||
var animal_ids []int64
|
||||
|
||||
for rows.Next() {
|
||||
var animal_id int64
|
||||
@ -220,10 +203,7 @@ func (e *Encounter) EncounteredCats(user_id, num int) ([]int64, error) {
|
||||
log.Println("扫描失败:", err)
|
||||
return nil, err
|
||||
}
|
||||
if !seen[animal_id] {
|
||||
seen[animal_id] = true
|
||||
temp = append(temp, animal_id)
|
||||
}
|
||||
animal_ids = append(animal_ids, animal_id)
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
@ -231,5 +211,5 @@ func (e *Encounter) EncounteredCats(user_id, num int) ([]int64, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return temp, nil
|
||||
return animal_ids, nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user