The FeatureStore SDK for Go lets you retrieve feature data from online data stores during model inference — including offline features, real-time features, and sequence features.
Prerequisites
Before you begin, ensure that you have:
-
A FeatureStore project, feature entities, feature views, and model features created, with data synchronized between the online and offline stores. See Configure FeatureStore projects.
-
An AccessKey ID and an AccessKey secret. See Create an AccessKey pair.
-
Your application running inside a virtual private cloud (VPC). The FeatureStore client connects to online data stores over a VPC — for example, Hologres is only accessible over a specific VPC.
Store your AccessKey ID and AccessKey secret as environment variables instead of hardcoding them in your code. See Configure environment variables.
Install the SDK
go get github.com/aliyun/aliyun-pai-featurestore-go-sdk/v2
Get started
Step 1: Initialize the FeatureStore client
API
func NewFeatureStoreClient(regionId, accessKeyId, accessKeySecret, projectName string, opts ...ClientOption) (*FeatureStoreClient, error)
| Parameter | Description |
|---|---|
regionId |
The region where the instance resides |
accessKeyId |
The AccessKey ID used to access the storage services |
accessKeySecret |
The AccessKey secret used to access the storage services |
projectName |
The name of the FeatureStore project created in the Platform for AI (PAI) console |
Example
accessId := os.Getenv("AccessId")
accessKey := os.Getenv("AccessKey")
client, err := featurestore.NewFeatureStoreClient("cn-beijing", accessId, accessKey, "project_name")
Step 2: Retrieve feature data from a feature view
Use GetOnlineFeatures to fetch features from a feature view by join ID (primary key).
API
GetOnlineFeatures(joinIds []interface{}, features []string, alias map[string]string) ([]map[string]interface{}, error)
| Parameter | Description | |
|---|---|---|
joinIds |
The join IDs (primary keys) of the features to retrieve | |
features |
The feature names to retrieve. Use []string{"*"} to retrieve all features in the feature view |
|
alias |
Aliases for the retrieved features. Does not apply to sequence feature views | |
Example
// Get project by name
project, err := client.GetProject("project_name")
if err != nil {
// t.Fatal(err)
}
// Get feature view by name
user_feature_view := project.GetFeatureView("feature_view_name")
if user_feature_view == nil {
// t.Fatal("feature view not exist")
}
// Retrieve features for two keys
features, err := user_feature_view.GetOnlineFeatures([]interface{}{"key1", "key2"}, []string{"*"}, nil)
Response: offline or real-time feature view
Each element in the response corresponds to one join ID. Fields with no data in the online data store return an empty string.
[
{
"city": "Hefei",
"follow_cnt": 1,
"gender": "male",
"user_id": "100043186"
},
{
"city": "",
"follow_cnt": 5,
"gender": "male",
"user_id": "100060369"
}
]
Response: sequence feature view
Sequence features are returned as semicolon-delimited strings. Each suffix field (__event, __event_time, __item_id, __playtime, __ts) holds the corresponding attribute values in the same order as the feature sequence.
The following example uses this sequence feature configuration:
| Offline sequence feature field | Event name | Sequence length | Online sequence feature name |
|---|---|---|---|
| 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"
}
]
Step 3: Retrieve feature data from model features
Each model feature can be associated with multiple feature entities. Use GetOnlineFeatures to retrieve all entity features at once, or GetOnlineFeaturesWithEntity to retrieve features for a specific entity.
API
// Retrieve features for all entities
GetOnlineFeatures(joinIds map[string][]interface{}) ([]map[string]interface{}, error)
// Retrieve features for a specific entity
GetOnlineFeaturesWithEntity(joinIds map[string][]interface{}, featureEntityName string) ([]map[string]interface{}, error)
| Parameter | Description | |
|---|---|---|
joinIds |
A map of join ID names to their values. Specify all join IDs configured for the model feature | |
featureEntityName |
The name of the feature entity whose features to retrieve | |
Example
A model feature can be associated with multiple feature entities. The following example specifies two join IDs — user_id and item_id — matching the model feature configuration.
// Get project by name
project, err := client.GetProject("fs_test_ots")
if err != nil {
// t.Fatal(err)
}
// Get model feature by name
model_feature := project.GetModelFeature("rank")
if model_feature == nil {
// t.Fatal("model feature not exist")
}
// Retrieve features for all configured join IDs
features, err := model_feature.GetOnlineFeatures(map[string][]interface{}{"user_id": {"100000676", "100004208"}, "item_id": {"238038872", "264025480"}})
To retrieve features for a specific entity only:
features, err := model_feature.GetOnlineFeaturesWithEntity(map[string][]interface{}{"user_id": {"100000676", "100004208"}}, "user")
Response: model features without sequence features
[
{
"age": 26,
"city": "Shenyang",
"gender": "male",
"user_id": "100000676"
},
{
"age": 23,
"city": "Xi'an",
"gender": "male",
"user_id": "100004208"
}
]
Response: model features with sequence features
When you register model features, you can include offline sequence features for model training. Those sequence features are synchronized to the online data store and returned alongside regular features.
The sequence entity is typically the user. The following example uses this sequence feature configuration:
| Offline sequence feature field | Event name | Sequence length | Online sequence feature name |
|---|---|---|---|
| click_seq_50_seq | click | 50 | click_seq_50_seq |
[
{
"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": "#Workout tracking",
"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": "#Idiom story",
"user_id": "186569870"
}
]