service/feature/op.go (126 lines of code) (raw):

package feature import ( "fmt" "strings" "github.com/alibaba/pairec/v2/context" "github.com/alibaba/pairec/v2/module" ) type FeatureOp interface { UserTransOp(featureName string, source string, remove bool, normalizer Normalizer, user *module.User, context *context.RecommendContext) ItemTransOp(featureName string, source string, remove bool, normalizer Normalizer, user *module.User, item *module.Item, context *context.RecommendContext) } func NewFeatureOp(t string) FeatureOp { if t == "raw_feature" { return RawFeatureOp{} } else if t == "compose_feature" { return ComposeFeatureOp{} } else if t == "delete_feature" { return DeleteFeatureOp{} } else if t == "batch_raw_feature" { return BatchRawFeatureOp{} } else if t == "new_feature" { return CreateNewFeatureOp{} } else if t == "context_feature" { return ContextFeatureOp{} } panic(fmt.Sprintf("not find feature type:%s", t)) } type featureOp struct { } func (op featureOp) getRequestId(context *context.RecommendContext) string { if nil == context { return "" } return context.RecommendId } type RawFeatureOp struct { featureOp } // UserTransOp of RawFeatureOp to Trans user feature // it create new feature store in user properties func (op RawFeatureOp) UserTransOp(featureName string, source string, remove bool, normalizer Normalizer, user *module.User, context *context.RecommendContext) { comms := strings.Split(source, ":") if len(comms) >= 2 { value := user.StringProperty(comms[1]) user.AddProperty(featureName, value) if remove { user.DeleteProperty(comms[1]) } } } // ItemTransOp of RawFeatureOp to Trans item or user feature // it create new feature store in item properties func (op RawFeatureOp) ItemTransOp(featureName string, source string, remove bool, normalizer Normalizer, user *module.User, item *module.Item, context *context.RecommendContext) { comms := strings.Split(source, ":") if len(comms) >= 2 { if comms[0] == SOURCE_USER { value := user.StringProperty(comms[1]) item.AddProperty(featureName, value) if remove { user.DeleteProperty(comms[1]) } } else { var newValue interface{} value := item.StringProperty(comms[1]) newValue = value if normalizer != nil { newValue = normalizer.Apply(value) } item.AddProperty(featureName, newValue) if remove { item.DeleteProperty(comms[1]) } } } } type ComposeFeatureOp struct { featureOp } func (op ComposeFeatureOp) UserTransOp(featureName string, source string, remove bool, normalizer Normalizer, user *module.User, context *context.RecommendContext) { vals := strings.Split(source, ",") var featureValue string for _, val := range vals { comms := strings.Split(val, ":") if len(comms) >= 2 { value := user.StringProperty(comms[1]) featureValue += "_" + value if remove { user.DeleteProperty(comms[1]) } } } user.AddProperty(featureName, featureValue) } func (op ComposeFeatureOp) ItemTransOp(featureName string, source string, remove bool, normalizer Normalizer, user *module.User, item *module.Item, context *context.RecommendContext) { vals := strings.Split(source, ",") featureValue := featureName for _, val := range vals { comms := strings.Split(val, ":") if len(comms) >= 2 { if comms[0] == SOURCE_USER { value := user.StringProperty(comms[1]) // item.AddProperty(featureName, value) featureValue += "_" + value } else { var value string if comms[1] == "id" { value = string(item.Id) } else { value = item.StringProperty(comms[1]) } featureValue += "_" + value if remove { item.DeleteProperty(comms[1]) } } } } item.AddProperty(featureName, featureValue) } // ContextFeatureOp add context feature to user type ContextFeatureOp struct { //featureOp } func (op ContextFeatureOp) UserTransOp(featureName string, source string, remove bool, normalizer Normalizer, user *module.User, context *context.RecommendContext) { contextFeatures := context.GetParameter("features") if contextFeatures != nil { if ctxFeatures, ok := contextFeatures.(map[string]any); ok { user.AddProperties(ctxFeatures) } } } func (op ContextFeatureOp) ItemTransOp(featureName string, source string, remove bool, normalizer Normalizer, user *module.User, item *module.Item, context *context.RecommendContext) { }