-
Notifications
You must be signed in to change notification settings - Fork 6
/
boost_score_sort.go
103 lines (89 loc) · 2.84 KB
/
boost_score_sort.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package sort
import (
"errors"
"fmt"
"time"
"github.com/Knetic/govaluate"
"github.com/alibaba/pairec/v2/log"
"github.com/alibaba/pairec/v2/module"
"github.com/alibaba/pairec/v2/recconf"
)
type BoostScoreCondition struct {
filterParam *module.FilterParam
evaluableExpression *govaluate.EvaluableExpression
}
func NewBoostScoreCondition(config *recconf.BoostScoreCondition) (*BoostScoreCondition, error) {
condition := &BoostScoreCondition{}
if config.Expression != "" {
expression, err := govaluate.NewEvaluableExpression(config.Expression)
if err != nil {
return nil, err
}
condition.evaluableExpression = expression
}
filterParam := module.NewFilterParamWithConfig(config.Conditions)
condition.filterParam = filterParam
return condition, nil
}
type BoostScoreSort struct {
debug bool
filterAll bool
name string
conditions []*BoostScoreCondition
cloneInstances map[string]*BoostScoreSort
}
func NewBoostScoreSort(config recconf.SortConfig) *BoostScoreSort {
sort := BoostScoreSort{
debug: config.Debug,
filterAll: config.BoostScoreConditionsFilterAll,
name: config.Name,
cloneInstances: make(map[string]*BoostScoreSort),
}
for _, boostScoreConditionConfig := range config.BoostScoreConditions {
condition, err := NewBoostScoreCondition(&boostScoreConditionConfig)
if err != nil {
log.Error(fmt.Sprintf("BoostScoreCondition error:%v", err))
} else {
sort.conditions = append(sort.conditions, condition)
}
}
return &sort
}
func (s *BoostScoreSort) Sort(sortData *SortData) error {
if _, ok := sortData.Data.([]*module.Item); !ok {
return errors.New("sort data type error")
}
return s.doSort(sortData)
}
func (s *BoostScoreSort) doSort(sortData *SortData) error {
start := time.Now()
items := sortData.Data.([]*module.Item)
userProperties := sortData.User.MakeUserFeatures2()
for _, item := range items {
properties := item.GetProperties()
for _, condition := range s.conditions {
if flag, err := condition.filterParam.EvaluateByDomain(userProperties, properties); err == nil && flag {
properties["score"] = item.Score
result, err := condition.evaluableExpression.Evaluate(properties)
if err != nil {
log.Error(fmt.Sprintf("requestId=%s\tmodule=BoostScoreSort\titemId=%s\terror=%v", sortData.Context.RecommendId, item.Id, err))
} else {
if value, ok := result.(float64); ok {
if s.debug {
item.AddProperty("org_score", item.Score)
log.Info(fmt.Sprintf("requestId=%s\tmodule=BoostScoreSort\tname=%s\titemId=%s\torg_score=%f\tscore=%f",
sortData.Context.RecommendId, s.name, item.Id, item.Score, value))
}
item.Score = value
}
}
if !s.filterAll {
break
}
}
}
}
sortData.Data = items
sortInfoLogWithName(sortData, "BoostScoreSort", s.name, len(items), start)
return nil
}