FeatureStore Java SDK

更新时间:
复制 MD 格式

概述

FeatureStore Java SDK 是人工智能平台(PAI)下特征平台(FeatureStore)的 Java 客户端 SDK,提供特征数据的高性能读取和写入。

适用场景

  • 在线推理场景快速获取特征数据

  • 实时特征写入与更新

  • 序列特征读取

  • 模型特征批量获取

前提条件

在使用 FeatureStore Java SDK 之前,请确保已完成以下准备工作:

  • 已创建FeatureStore项目(Project)、特征实体(FeatureEntity)、特征视图(FeatureView)和模型特征(ModelFeature),并完成数据同步操作。具体操作,请参见配置FeatureStore项目

  • 已获取阿里云账户的AccessKey IDAccessKey Secret。具体操作,请参见创建AccessKey

    • 建议使用本地配置环境变量的方式保存AccessKey IDAccessKey Secret。具体操作,请参见配置环境变量

    • FeatureStore Java SDK支持零信任调用,详情请参见:管理访问凭据

快速开始

FeatureStore Java SDK地址见https://github.com/aliyun/aliyun-pai-featurestore-java-sdk

在 pom.xml 中添加以下依赖:

<dependency>
  <groupId>com.aliyun.openservices.aiservice</groupId>
  <artifactId>paifeaturestore-sdk</artifactId>
  <version>1.2.8</version>
</dependency>

初始化配置类Configuration(以regioncn-hangzhou为例)。

public class Constants {
    public static String accessId = "";
    public static String accessKey = "";
    public static String username = "";
    public static String password = "";

    static {
        accessId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
        username = System.getenv("FEATUREDB_USERNAME");
        password = System.getenv("FEATUREDB_PASSWORD");
    }
} 
// 配置regionId、accessId、accessKey以及项目名称
Configuration configuration = new Configuration("cn-hangzhou",Constants.accessId,Constants.accessKey,"my_project");

参数介绍

参数名

类型

必填

说明

示例值

regionId

String

地域ID

cn-hangzhou

accessKeyId

String

阿里云账号 AccessKey ID

从环境变量获取

accessKeySecret

String

阿里云账号 AccessKey Secret

从环境变量获取

projectName

String

FeatureStore 项目名称

my_project

username

String

FeatureDB 必填

FeatureDB 用户名,仅在线数据源为 FeatureDB 时需配置

从环境变量获取

password

String

FeatureDB 必填

FeatureDB 密码,仅在线数据源为 FeatureDB 时需配置

从环境变量获取

说明

由于SDK是直连在线数据源,客户端需要在VPC环境运行。例如FeatureDB数据源一般在VPC环境连接进行数据访问,为了追求更好的性能也可以配置FeatureDB VPC网络高速连通,配置详情及性能对比测试参见:VPC网络高速连通。本地环境调试时可配置公网地址访问,参考示例如下:

configuration.setUsername(Constants.username);
configuration.setPassword(Constants.password);
//公网地址
configuration.setDomain("paifeaturestore.cn-hangzhou.aliyuncs.com");

// 初始化客户端,true(代表使用公网访问)
FeatureStoreClient featureStoreClient = new FeatureStoreClient(apiClient, true);

读取功能

获取 FeatureView 特征数据

通过 FeatureView 获取在线特征数据,支持离线特征、实时特征和序列特征的读取。

接口说明

public FeatureResult getOnlineFeatures(String[] joinIds);
public FeatureResult getOnlineFeatures(String[] joinIds, String[] features, Map<String, String> aliasFields);

参数说明

参数名

类型

必填

说明

joinIds

String[]

join_id 值列表,用于查询特征数据

features

String[]

需要返回的特征字段列表,不指定默认new String[]{"*"} 即返回全部字段

aliasFields

Map<String, String>

特征字段别名映射,返回数据时显示别名

示例

  • 示例一:获取离线特征 FeatureView 的特征数据

    • 获取 FeatureView 及离线表同步的数据

      // 获取项目
      Project project = featureStoreClient.getProject("my_project");
      if (project == null) {
          throw new RuntimeException("Project not found");
      }
      
      // 获取离线特征 FeatureView
      FeatureView offlineView = project.getFeatureView("user_features");
      if (offlineView == null) {
          throw new RuntimeException("FeatureView not found");
      }
      
      // 获取离线特征数据
      FeatureResult offlineResult = offlineView.getOnlineFeatures(
          new String[]{"100001167", "100004088", "100006646"},
          new String[]{"*"},
          null
      );
      
    • 返回示例结果

      [
        {
          "user_id": 100001167,
          "gender": "male",
          "age": 28,
          "city": "沈阳市",
          "item_cnt": 0,
          "follow_cnt": 0,
          "follower_cnt": 0,
          "register_time": 1696658585,
          "tags": "2"
        },
        {
          "user_id": 100004088,
          "gender": "female",
          "age": 28,
          "city": "长春市",
          "item_cnt": 0,
          "follow_cnt": 8,
          "follower_cnt": 0,
          "register_time": 1695618449,
          "tags": "1"
        }
      ]
      
  • 示例二:获取实时特征 FeatureView 的特征数据

    • 获取 FeatureView 及在线表的数据

      // 获取实时特征 FeatureView
      FeatureView onlineView = project.getFeatureView("user_profile_view");
      if (onlineView == null) {
          throw new RuntimeException("FeatureView not found");
      }
      
      // 获取实时特征数据
      FeatureResult onlineResult = onlineView.getOnlineFeatures(
          new String[]{"user_001", "user_002", "user_003"},
          new String[]{"*"},
          null
      );
      
    • 返回示例结果

      [
        {
          "user_id": "user_001",
          "user_nickname": "科技爱好者"
        },
        {
          "user_id": "user_002",
          "user_nickname": "编程达人"
        },
        {
          "user_id": "user_003",
          "user_nickname": "数据分析师"
        }
      ]
      
  • 示例三:获取序列特征 FeatureView 的特征数据

    • 获取 SequenceFeatureView 类型的序列特征数据

      // 获取序列特征 View
      SequenceFeatureView seqFeatureView = project.getSeqFeatureView("user_seq_features");
      if (seqFeatureView == null) {
          throw new RuntimeException("SequenceFeatureView not found");
      }
      
      // 获取序列特征
      FeatureResult seqResult = seqFeatureView.getOnlineFeatures(
          new String[]{"157843277", "157843278"}
      );
      
    • 返回示例结果

      [
        {
          "user_id": "157843277",
          "click_50_seq": "null;200167895",
          "click_50_seq_item_id": "null;200167895",
          "click_50_seq_event": "null;click",
          "click_50_seq_playtime": "null;15.0",
          "click_50_seq_event_time": "null;1704684504747",
          "click_50_seq_ts": "625662604;625662604"
        },
        {
          "user_id": "157843278",
          "click_50_seq": "null;299049390",
          "click_50_seq_item_id": "null;299049390",
          "click_50_seq_event": "null;click",
          "click_50_seq_playtime": "null;32.15",
          "click_50_seq_event_time": "null;1698180365",
          "click_50_seq_ts": "1704292547792;1704292547792"
        }
      ]
      
    • 序列特征字段说明:返回数据字段格式为 {seq_name}_seq_{field}

      字段格式

      说明

      {seq_name}_seq

      行为序列主键列表,多个值用分号分隔

      {seq_name}_seq_item_id

      序列中的物品ID列表

      {seq_name}_seq_event

      序列中的事件类型列表(如 click、view)

      {seq_name}_seq_playtime

      序列中的播放时长列表

      {seq_name}_seq_event_time

      序列中的事件时间戳列表

      {seq_name}_seq_ts

      序列时间戳列表

获取 ModelFeature 关联特征

通过 Model 获取关联的所有 FeatureEntity 特征数据,支持上级-下级 Entity 层级关系。

接口说明

// 获取所有根实体及其关联的下级实体特征
public FeatureResult getOnlineFeatures(Map<String, List<String>> joinIds);

// 获取指定 Entity 及其下级 Entity 特征
public FeatureResult getOnlineFeaturesWithEntity(Map<String, List<String>> joinIds, String featureEntityName);

参数说明

参数名

类型

必填

说明

joinIds

Map<String, List<String>>

joinIdsmap集合。keyJoinId的名称,valuesJoinId的值。

featureEntityName

String

指定获取某个 FeatureEntity 的特征数据

Model 可关联多个 FeatureEntity,存在上下级嵌套关系:

* 上级 Entity:包含主特征字段 + 关联下级 Entity 的字段

* 下级 Entity:被上级 Entity 引用,包含独立的特征字段

image

获取特征时,只需传入根实体的 join_id,SDK 会自动根据上级实体的特征值获取下级实体的特征。

不同场景示例

场景1:获取 Model 关联的全部特征

调用 getOnlineFeatures 传入所有根实体的 join_id,SDK 自动获取 Model 关联的全部特征(包括下级实体)。

Model model = project.getModelFeature("model_fv1");
if (null == model) {
    throw  new RuntimeException("model not found");
}

// 传入所有根实体的 join_id
Map<String, List<String>> joinIds = new HashMap<>();
joinIds.put("item_id", Arrays.asList("1001", "1002", "1003"));
joinIds.put("user_id", Arrays.asList("U001", "U002", "U003"));

// 会一并获取所有根实体及其关联下级实体的特征
FeatureResult result = 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 侧全部特征。

Map<String, List<String>> joinIds = new HashMap<>();
joinIds.put("item_id", Arrays.asList("1001", "1002", "1003"));

// 指定获取 item Entity 的特征
// item侧关联下级实体 author、category,一并返回
FeatureResult result = 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 本身的特征字段。

Map<String, List<String>> joinIds = new HashMap<>();
joinIds.put("author_id", Arrays.asList("A001", "A002", "A003"));

// 指定获取 author Entity 的特征
// author侧无下级实体,只返回 author侧特征
FeatureResult result = model.getOnlineFeaturesWithEntity(joinIds, "author");

返回示例:

{
  "author_id": "A001",
  "author_name": "张三",
  "author_fans_count": 10000
}

ModelFeature 包含序列特征示例

当 ModelFeature 关联序列特征 FeatureView 时,返回数据中会包含序列特征字段:

Model model = project.getModelFeature("model_with_seq");
if (null == model) {
    throw  new RuntimeException("model not found");
}

Map<String, List<String>> joinIds = new HashMap<>();
joinIds.put("user_id", Arrays.asList("100001167", "100024146"));
joinIds.put("item_id", Arrays.asList("200138790", "200385417"));

FeatureResult result = model.getOnlineFeatures(joinIds);

返回示例:

[
  {
    "user_id": "100001167",
    "gender": "male",
    "age": 28,
    "city": "沈阳市",
    "item_id": "200138790",
    "title": "#成语故事",
    "click_count": 2,
    "click_50_seq": "null;204153583",
    "click_50_seq_item_id": "null;204153583",
    "click_50_seq_event": "null;click",
    "click_50_seq_playtime": "null;98.94",
    "click_50_seq_ts": "1704292557212;1704292557212"
  },
  {
    "user_id": "100024146",
    "gender": "male",
    "age": 28,
    "city": "宁波市",
    "item_id": "200385417",
    "title": "#健身打卡",
    "click_count": 4,
    "click_50_seq": "null;299049390",
    "click_50_seq_item_id": "null;299049390",
    "click_50_seq_event": "null;click",
    "click_50_seq_playtime": "null;32.15",
    "click_50_seq_ts": "1704292547792;1704292547792"
  }
]

写入功能

将特征数据实时写入 FeatureDB 数据源,支持实时特征和行为序列特征的写入。

适用场景

  • 实时更新用户特征(如在线特征更新)

  • 写入用户行为序列数据(点击、播放等事件)

  • 实时特征数据的部分字段更新(不影响其他字段)

说明

目前写入接口仅支持在线数据源为 FeatureDB 的实时特征视图和行为序列特征视图,初始化时需配置 FeatureDB 用户名和密码。

实时特征写入

整行更新

FeatureView featureView = project.getFeatureView("user_feature_view");
if (null == featureView) {
    throw  new RuntimeException("featureview not found");
}

// 构造写入数据
Map<String, Object> record = new HashMap<>();
record.put("user_id", "user_001");
record.put("name", "张三");
record.put("age", 28);
record.put("city", "北京");

featureView.writeFeatures(Arrays.asList(record));
featureView.writeFlush();

方法

参数

必填

说明

writeFeatures

List<Map<String,Object>>

批量写入数据

writeFlush

-

-

确保数据完成写入(调用后不能再写入)

部分字段更新

List<Map<String, Object>> writeData = new ArrayList<>();
Map<String, Object> record = new HashMap<>();
record.put("user_id", "user_001");
record.put("name", "李四");
writeData.add(record);
// 默认整行替换,部分字段更新需指定 InsertMode
featureView.writeFeatures(writeData, InsertMode.PartialFieldWrite);

序列特征写入

序列特征写入用于实时记录用户行为事件(点击、播放、购买等),支持在线推理场景的行为序列特征构建。

示例

SequenceFeatureView sequenceFeatureView = project.getSeqFeatureView("sequence");
if (null == seqFeatureView) {
    throw new RuntimeException("sequence feature view not found");
}

// 构造序列数据
List<Map<String, Object>> writeData = new ArrayList<>();
Map<String, Object> data = new HashMap<>();
data.put("request_id", 901850344);
data.put("user_id", "172040759");
data.put("page", "home");
data.put("net_type", "wifi");
data.put("day_h", 17);
data.put("week_day", 6);
data.put("event_unix_time", System.currentTimeMillis()/1000);
data.put("item_id", "223466789");
data.put("event","click");
data.put("playtime", 54.7296554003366);
writeData.add(data);
sequenceFeatureView.writeFeatures(writeData);
sequenceFeatureView.writeFlush();

相关文档