概述
FeatureStore Go SDK 是人工智能平台(PAI)下特征平台(FeatureStore)的 Go 客户端 SDK,提供特征数据的高性能读取和写入。
适用场景
在线推理场景快速获取特征数据
实时特征写入与更新
支持行为数据读取和序列特征拼接
模型特征批量获取
前提条件
在使用 FeatureStore Go SDK 之前,请确保已完成以下准备工作:
* 已创建 FeatureStore 项目(Project)、特征实体(FeatureEntity)、特征视图(FeatureView)和模型特征(ModelFeature),并完成数据同步操作。具体操作,请参见 配置FeatureStore项目。
* 已获取阿里云账户的 AccessKey ID 和 AccessKey Secret。具体操作,请参见 创建AccessKey。
快速开始
FeatureStore Go SDK地址见:https://github.com/aliyun/aliyun-pai-featurestore-go-sdk
执行以下命令安装 SDK:
go get github.com/aliyun/aliyun-pai-featurestore-go-sdk/v2
import (
"os"
featurestore "github.com/aliyun/aliyun-pai-featurestore-go-sdk/v2/featurestore"
)
accessId := os.Getenv("AccessId")
accessKey := os.Getenv("AccessKey")
regionId := "cn-hangzhou"
projectName := "fs_test_ots"
client, err := featurestore.NewFeatureStoreClient(regionId, accessId, accessKey, projectName)
如若从 FeatureDB 读写数据,需配置 FeatureDB 用户名和密码:
username := os.Getenv("FEATUREDB_USERNAME")
password := os.Getenv("FEATUREDB_PASSWORD")
client, err := featurestore.NewFeatureStoreClient(
regionId, accessId, accessKey, projectName,
featurestore.WithFeatureDBLogin(username, password),
)
参数介绍
参数名 | 类型 | 必填 | 说明 | 示例 |
regionId | String | 是 | 地域ID | cn-hangzhou |
accessId | String | 否 | 阿里云账号 AccessKey ID | 从环境变量获取 |
accessKey | String | 否 | 阿里云账号 AccessKey Secret | 从环境变量获取 |
projectName | String | 是 | FeatureStore 项目名称 | my_project |
username | String | FeatureDB 必填 | FeatureDB 用户名,仅在线数据源为 FeatureDB 时需配置 | featuredb_user |
password | String | FeatureDB 必填 | FeatureDB 密码,仅在线数据源为 FeatureDB 时需配置 | featuredb_password |
SDK 默认直连在线数据源(如 FeatureDB),客户端需要在 VPC 环境运行才能连接。本地调试时可使用 WithTestMode() 启用公网访问,但生产环境请勿启用。
// 本地调试使用公网地址
client, err := featurestore.NewFeatureStoreClient(
regionId, accessId, accessKey, projectName,
featurestore.WithTestMode(),
featurestore.WithFeatureDBLogin(username, password),
)
可选配置项
配置项 | 用途 | 示例 |
WithFeatureDBLogin() | FeatureDB 认证信息 | featurestore.WithFeatureDBLogin("admin", "pwd") |
WithTestMode() | 本地调试,使用公网地址 | featurestore.WithTestMode() |
读取功能
获取 FeatureView 特征数据
通过 FeatureView 获取在线特征数据,支持离线特征、实时特征和序列特征的读取。
接口说明
GetOnlineFeatures(joinIds []interface{}, features []string, alias map[string]string) ([]map[string]interface{}, error)
参数说明
参数名 | 类型 | 必填 | 说明 |
joinIds | []interface{} | 是 | join_id 值列表,用于查询特征数据 |
features | []string | 否 | 需要返回的特征字段列表, |
alias | map[string]string | 否 | 特征字段别名映射,返回数据时显示别名 |
示例
project, err := client.GetProject("fs_test_ots")
if err != nil {
log.Fatal(err)
}
userFeatureView := project.GetFeatureView("user_fea")
if userFeatureView == nil {
log.Fatal("feature view not exist")
}
features, err := userFeatureView.GetOnlineFeatures(
[]interface{}{"100043186", "100060369"},
[]string{"*"},
nil,
)
离线/实时FeatureView特征数据示例结果
[ { "city":"合肥市", "follow_cnt":1, "gender":"male", "user_id":"100043186" }, { "city":"", "follow_cnt":5, "gender":"male", "user_id":"100060369" } ]序列特征FeatureView特征数据示例结果
假设序列特征读取配置如下
离线序列特征字段
事件名称
序列长度
在线序列特征名称
click_seq_50_seq
click
50
click_seq_50_seq
expr_seq_100_seq
expr
100
expr_seq_100
返回示例结果
[ { "click_seq_50_seq": "216751275;228787053;220852269;242884721", "click_seq_50_seq__event": "click;click;click;click", "click_seq_50_seq__event_time": "1699128398;1699128398;1699118623;1699118623", "click_seq_50_seq__item_id": "216751275;228787053;220852269;242884721", "click_seq_50_seq__playtime": "65.40;72.06;104.69;62.74", "click_seq_50_seq__ts": "389018;389018;398793;398793", "expr_seq_100": "207474427;216751275;228787053;247136848;270584471;299485479;220852269;242884721;245999124;265863707", "expr_seq_100__event": "expr;expr;expr;expr;expr;expr;expr;expr;expr;expr", "expr_seq_100__event_time": "1699128398;1699128398;1699128398;1699128398;1699128398;1699128398;1699118623;1699118623;1699118623;1699118623", "expr_seq_100__item_id": "207474427;216751275;228787053;247136848;270584471;299485479;220852269;242884721;245999124;265863707", "expr_seq_100__playtime": "0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00", "expr_seq_100__ts": "389018;389018;389018;389018;389018;389018;398793;398793;398793;398793", "user_id": "186569075" }, { "click_seq_50_seq": "201741544;236327912;293320498", "click_seq_50_seq__event": "click;click;click", "click_seq_50_seq__event_time": "1699178245;1699178245;1699178245", "click_seq_50_seq__item_id": "201741544;236327912;293320498", "click_seq_50_seq__playtime": "97.41;70.32;135.21", "click_seq_50_seq__ts": "339171;339171;339171", "expr_seq_100": "201741544;224940066;236327912;240253906;247562151;293320498", "expr_seq_100__event": "expr;expr;expr;expr;expr;expr", "expr_seq_100__event_time": "1699178245;1699178245;1699178245;1699178245;1699178245;1699178245", "expr_seq_100__item_id": "201741544;224940066;236327912;240253906;247562151;293320498", "expr_seq_100__playtime": "0.00;0.00;0.00;0.00;0.00;0.00", "expr_seq_100__ts": "339171;339171;339171;339171;339171;339171", "user_id": "186569870" } ]
获取 ModelFeature 关联特征
通过 Model 获取关联的所有 FeatureEntity 特征数据,支持上级-下级 Entity 层级关系。
接口说明
// 获取所有根实体及其关联的下级实体特征
GetOnlineFeatures(joinIds map[string][]interface{}) ([]map[string]interface{}, error)
// 获取指定 Entity 及其下级 Entity 特征
GetOnlineFeaturesWithEntity(joinIds map[string][]interface{}, featureEntityName string) ([]map[string]interface{}, error)
参数说明
参数名 | 类型 | 必填 | 说明 |
joinIds | map[string][]interface{} | 是 | join_id 映射,key 为 join_id 名称,value 为值列表 |
featureEntityName | string | 否 | 指定获取某个 FeatureEntity 的特征数据 |
Entity 层级关系
ModelFeature 可关联多个 FeatureEntity,存在上下级嵌套关系:
* 上级 Entity:包含主特征字段 + 关联下级 Entity 的字段
* 下级 Entity:被上级 Entity 引用,包含独立的特征字段
获取特征时,只需传入根实体的 join_id,SDK 会自动根据上级实体的特征值获取下级实体的特征。
不同场景示例
场景1:获取 Model 关联的全部特征
调用 GetOnlineFeatures 传入所有根实体的 join_id,SDK 自动获取 Model 关联的全部特征(包括下级实体)。
model := project.GetModelFeature("model_fv1")
if model == nil {
t.Fatal("model feature not exist")
}
// 传入所有根实体的 join_id
joinIds := map[string][]interface{}{
"user_id": {"U001", "U002", "U003"},
"item_id": {"1001", "1002", "1003"},
}
// 会一并获取所有根实体及其关联下级实体的特征
features, err := model.GetOnlineFeatures(joinIds)
返回示例:
{
"item_id": "1001",
"item_title": "智能手表",
"item_price": 299.00,
"author_id": "A001",
"author_name": "张三",
"author_fans_count": 10000,
"category_id": "C001",
"category_name": "电子产品",
"category_level": 1,
"user_id": "U001",
"user_age": 28,
"user_gender": "male"
}
场景2:获取指定 Entity 侧特征(含下级实体)
调用 GetOnlineFeaturesWithEntity 指定 Entity 名称,获取该 Entity 及其下级实体特征。示例中 item Entity 关联 author、category 两个下级实体,返回 item 侧全部特征。
joinIds := map[string][]interface{}{
"item_id": {"1001", "1002", "1003"},
}
// 指定获取 item Entity 的特征
// item侧关联下级实体 author、category,一并返回
features, err := model.GetOnlineFeaturesWithEntity(joinIds, "item")
返回示例:
{
"item_id": "1001",
"item_title": "智能手表",
"item_price": 299.00,
"author_id": "A001",
"author_name": "张三",
"author_fans_count": 10000,
"category_id": "C001",
"category_name": "电子产品",
"category_level": 1
}
场景3:获取指定 Entity 侧特征(无下级实体)
调用 GetOnlineFeaturesWithEntity 指定实体名称,获取该实体特征。示例中 author 实体无下级实体,只返回 author 本身的特征字段。
joinIds := map[string][]interface{}{
"author_id": {"A001", "A002", "A003"},
}
// 指定获取 author Entity 的特征
// author侧无下级实体,只返回 author侧特征
features, err := model.GetOnlineFeaturesWithEntity(joinIds, "author")
返回示例:
{
"author_id": "A001",
"author_name": "张三",
"author_fans_count": 10000
}
ModelFeature 包含序列特征示例
当 ModelFeature 关联序列特征 FeatureView 时,返回数据中会包含序列特征字段:
序列特征对应FeatureEntity一般为user,示例中有两个join_id、user_id和item_id。获取特征的时候需要设置相同的ID数量。
假设序列特征读取配置如下:
离线序列特征字段
事件名称
序列长度
在线序列特征名称
click_seq_50_seq
click
50
click_seq_50_seq
// get ModelFeature by name model := project.GetModelFeature("model_with_seq") if model == nil { t.Fatal("model feature not exist") } joinIds := map[string][]interface{}{ "user_id": {"186569075", "186569870"}, "item_id": {"299485479", "207474427"}, } // get online features features, err := model.GetOnlineFeatures(joinIds)返回示例结果
[ { "age": 51, "author": 147848300, "category": "7", "city": "", "click_count": 0, "click_seq_50_seq": "216751275;228787053;220852269;242884721", "click_seq_50_seq__event": "click;click;click;click", "click_seq_50_seq__event_time": "1699128398;1699128398;1699118623;1699118623", "click_seq_50_seq__item_id": "216751275;228787053;220852269;242884721", "click_seq_50_seq__playtime": "65.40;72.06;104.69;62.74", "click_seq_50_seq__ts": "391447;391447;401222;401222", "duration": 48, "follow_cnt": 2, "follower_cnt": 0, "gender": "female", "item_cnt": 0, "item_id": 299485479, "praise_count": 2, "pub_time": 1697885713, "register_time": 1696582012, "tags": "0", "title": "#健身打卡", "user_id": "186569075" }, { "age": 28, "author": 119734983, "category": "18", "city": "", "click_count": 0, "click_seq_50_seq": "201741544;236327912;293320498", "click_seq_50_seq__event": "click;click;click", "click_seq_50_seq__event_time": "1699178245;1699178245;1699178245", "click_seq_50_seq__item_id": "201741544;236327912;293320498", "click_seq_50_seq__playtime": "97.41;70.32;135.21", "click_seq_50_seq__ts": "341600;341600;341600", "duration": 15, "follow_cnt": 0, "follower_cnt": 2, "gender": "male", "item_cnt": 0, "item_id": 207474427, "praise_count": 79, "pub_time": 1697731285, "register_time": 1699135393, "tags": "1", "title": "#成语故事", "user_id": "186569870" } ]
写入功能
将特征数据实时写入 FeatureDB 数据源,支持实时特征和序列特征的写入。
适用场景
实时更新用户特征(如在线特征更新)
写入用户行为序列数据(点击、播放等事件)
实时特征数据的部分字段更新(不影响其他字段)
目前写入接口仅支持在线数据源为 FeatureDB 的实时特征视图和行为序列特征视图,需配置 FeatureDB 用户名和密码。
实时特征写入
整行更新
project, err := client.GetProject("test_pro1")
if err != nil {
log.Fatal(err)
}
featureView := project.GetFeatureView("user_feature_view")
if featureView == nil {
t.Fatal("feature view not exist")
}
// 构造写入数据
writeData := make([]map[string]interface{}, 0)
record := map[string]interface{}{
"user_id": "user_001",
"name": "张三",
"age": 28,
"city": "北京",
}
writeData := append(writeData, record)
// 写入数据
featureView.WriteFeatures(writeData)
// 强制刷新(确保数据完成写入)
featureView.WriteFlush()
方法 | 参数 | 必填 | 说明 |
WriteFeatures | []map[string]interface{} | 是 | 批量写入数据 |
WriteFlush | 无 | - | 确保数据完成写入(调用后不能再写入) |
部分字段更新
默认整行替换,部分字段更新需指定 InsertMode:
import "github.com/aliyun/aliyun-pai-featurestore-go-sdk/v2/constants"
record = map[string]interface{}{
"user_id": "user_001",
"name": "李四",
}
writeData := append(writeData, record)
featureView.WriteFeaturesWithInsertMode(writeData, constants.Partial_Field_Write)
// 强制刷新(确保数据完成写入)
featureView.WriteFlush()
序列特征写入
序列特征写入用于实时记录用户行为事件(点击、播放、购买等),支持在线推理场景的行为序列特征构建。
示例
sequenceFeatureView := project.GetFeatureView("sequence")
if sequenceFeatureView == nil {
t.Fatal("sequence featureview not found")
}
// 构造序列数据
sequenceWriteData := make([]map[string]interface{}, 0)
for i := 0; i < 10; i++ {
data := make(map[string]interface{})
data["request_id"] = int64(901850344 + i)
data["user_id"] = fmt.Sprintf("%d", 1000+i+1)
data["page"] = "home"
data["net_type"] = "wifi"
data["day_h"] = 17
data["week_day"] = 6
data["event_unix_time"] = time.Now().Unix()
data["item_id"] = fmt.Sprintf("22346678%d", i)
data["event"] = "click"
data["playtime"] = 54.7296554003366 + float64(i)
sequenceWriteData = append(sequenceWriteData, data)
}
err = sequenceFeatureView.WriteFeatures(sequenceWriteData)
if err != nil {
t.Fatal(err)
}
sequenceFeatureView.WriteFlush()