123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- package module
- import (
- "errors"
- "strconv"
- "sync"
- "gitlab.alibaba-inc.com/pai_biz_arch/pairec/context"
- )
- type User struct {
- Id UID `json:"uid"`
- Vector string
- Properties map[string]interface{} `json:"properties"`
- mutex sync.RWMutex
- }
- func NewUser(id string) *User {
- user := User{
- Id: UID(id),
- }
- user.Properties = make(map[string]interface{})
- return &user
- }
- func NewUserWithContext(id UID, context *context.RecommendContext) *User {
- user := NewUser(string(id))
- user.AddProperty("uid", string(id))
- features := context.GetParameter("features")
- if features != nil {
- if _, ok := features.(map[string]interface{}); ok {
- for k, v := range features.(map[string]interface{}) {
- user.AddProperty(k, v)
- }
- }
- }
- return user
- }
- func (u *User) AddProperty(key string, value interface{}) {
- u.mutex.Lock()
- u.Properties[key] = value
- u.mutex.Unlock()
- }
- func (u *User) FloatProperty(key string) (float64, error) {
- //u.mutex.RLock()
- //defer u.mutex.RUnlock()
- val, ok := u.Properties[key]
- if !ok {
- return float64(0), errors.New("property key not exist")
- }
- switch value := val.(type) {
- case float64:
- return value, nil
- case int:
- return float64(value), nil
- case string:
- f, err := strconv.ParseFloat(value, 64)
- return f, err
- default:
- return float64(0), errors.New("unspport type")
- }
- }
- func (u *User) MakeUserFeatures() (features map[string]interface{}) {
- features = make(map[string]interface{})
- for k, v := range u.Properties {
- if k == "type" {
- continue
- }
- if s, ok := v.(float64); ok {
- features[k] = s
- continue
- }
- if str, ok := v.(string); ok {
- if s, err := strconv.ParseFloat(str, 64); err == nil {
- features[k] = s
- continue
- }
- }
- features[k] = v
- }
- return
- }
- // MakeUserFeatures2 for easyrec processor
- func (u *User) MakeUserFeatures2() (features map[string]interface{}) {
- features = make(map[string]interface{}, len(u.Properties))
- for k, v := range u.Properties {
- features[k] = v
- }
- return
- }
- func (u *User) StringProperty(key string) string {
- u.mutex.RLock()
- defer u.mutex.RUnlock()
- val, ok := u.Properties[key]
- if !ok {
- return ""
- }
- switch value := val.(type) {
- case string:
- return value
- case int:
- return strconv.Itoa(value)
- case float64:
- return strconv.Itoa(int(value))
- }
- return ""
- }
- func (u *User) DeleteProperty(key string) {
- u.mutex.Lock()
- delete(u.Properties, key)
- u.mutex.Unlock()
- }
- func (u *User) DeleteProperties(features []string) {
- u.mutex.Lock()
- for _, key := range features {
- delete(u.Properties, key)
- }
- u.mutex.Unlock()
- }
- func (u *User) IntProperty(key string) (int, error) {
- //u.mutex.RLock()
- //defer u.mutex.RUnlock()
- val, ok := u.Properties[key]
- if !ok {
- return int(0), errors.New("property key not exist")
- }
- switch value := val.(type) {
- case float64:
- return int(value), nil
- case int:
- return value, nil
- case uint:
- return int(value), nil
- case int32:
- return int(value), nil
- case int64:
- return int(value), nil
- case string:
- return strconv.Atoi(value)
- default:
- return int(0), errors.New("unspport type")
- }
- }
- func (u *User) GetProperty(key string) interface{} {
- //u.mutex.RLock()
- //defer u.mutex.RUnlock()
- val, ok := u.Properties[key]
- if !ok {
- return nil
- }
- return val
- }
|