相关概念
标签
一个标签代表用户某一个特征,贯穿整个用户运营周期,支撑人群圈选、数据分析、人群判定等基础能力。
标签类型
- 原子标签
- 单维度标签:如性别、年龄、消费力,属于用户基本属性。
- 多维度标签:如用户在母婴行业下的消费力,通常关联行业、商家、商品、店铺等维度,表示用户在某个维度下的特征。
- 组合标签
- 组合标签:多个原子标签的组合,更加贴近业务语义。
标签时效性
- 离线:T+1更新,用于数据分析,人群圈选
- 实时:秒级更新,用于人群id实时判定
码表
- 将标签值映射为业务语义。如性别标签,存储层使用int表示,展示时,将其映射为男女。
- 对标签值进行补充说明。如用户偏好商家标签,存储层存储商家id,展示时,补全商家名称、logo、等级等额外信息。
码表类型
- 普通码表:平铺展示,如性别
- 级联码表:以树的形式展示,如商品类目,各类目存在父子关系
离线数据构建
标签
架构图
整体架构
领域设计
标签
public class Tag {
private final String tagId; // 标签id
private final String name; // 标签名称
private final String description; // 标签描述
private final Boolean isRealtime; // 是否实时
private final TagSchema schema; // 标签格式
private final TagView view; // 前端展示逻辑
private final Map<String, String> dim2dict;// 维度2码表id
}
public class TagSchema {
private final TagSchemaTypeEnum schemaType;// 标签格式枚举
private final AtomTagCondition atomTag; // 原子标签条件
private final CombTagCondition combTag; // 组合标签条件
}
public class AtomTagCondition {
private TagEntity targetTag; // 标签
private Map<String, TagEntity> dim; // 维度
private String relatedNonRealtimeTagId; // 关联的离线标签ID
private Boolean isTemplateTag; // 是否动态模板标签,例如C端距今XX天
}
public class CombTagCondition {
private String targetTagId; // 标签id
private StandardConditionNode conditionNode;// 组合条件,dsl
}
public class TagEntity {
private String tagCode; // 平台tagCode
private String tagOptionCode; // 平台tagOptionCode
private FieldDataTypeEnum fieldDataType; // 标签类型(C端使用)
}
public class TagView {
private final List<OptionView> optionViews;// 标签维度
}
public class OptionView {
private String optionCode; // 维度code
private TagUiTypeEnum uiType; // 前端Ui渲染类型
private List<OptionFeature> optionFeature;// 标签值选项
private Boolean isIdValue; // 是否是id
private Boolean isRequire; // 是否必填
}
public class OptionFeature {
private String description;
private Boolean chooseOperator; // 是否需要自定义操作符
private List<OperatorTypeEnum> operators;// 可使用的操作符
private Boolean chooseValue; // 是否需要自定义值
private TagValueSourceTypeEnum valueSourceType; // 值来源 STATIC下方定义好的 SIN_SEARCH单选搜索 MULT_SEARCH多选搜索 INPUT用户输入
private List<List<Entity>> values; // 值
private String unitName; // 单位
}
public interface TagService {
// 新增标签
void addTag(Tag tag);
// 搜索标签
PageData<Tag> searchTagsByNameOrderByGivenTagIdList(List<String> tagIds, String name, Page page);
// 获取标签
Tag getTagById(String tagId);
// 批量获取标签
List<Tag> batchGetTagsByIds(List<String> ids);
}
标签规则语言
public class StandardConditionRoot {
private final LogicTypeEnum logic; // 逻辑条件 AND OR
private final StandardConditionNode offlineCondition;// 离线条件
private final StandardConditionNode realtimeCondition;// 实时条件
}
public class StandardConditionNode {
private LogicTypeEnum logic; // 逻辑条件
private List<StandardConditionNode> children;// 子逻辑节点
private List<StandardConditionLeaf> leafs;// 叶子节点
}
public class StandardConditionLeaf {
private StandardConditionLeafTypeEnum leafType;// 叶子结点类型
private StandardTagCondition tagCondition;// 标签条件
private StandardCrowdCondition crowdCondition;// 人群条件
}
public class StandardTagCondition {
private String tagId; // 标签id
private List<StandardDimCondition> dimConditions; // 维度值
}
public class StandardDimCondition {
private String dimCode; // 维度code
private List<StandardDimValue> values;// 维度值
}
public class StandardDimValue {
private OperatorTypeEnum operator; // 操作符
private List<String> values; // 值
}
public class StandardCrowdCondition {
private String crowdId; // 人群id
}
public interface DslTransferService {
// 前端规则2业务规则
StandardConditionRoot web2standard(WebCondition condition);
// 业务规则2电商dmp规则
Where standard2dmp(StandardConditionRoot root, boolean isTransRealtime2Offline);
// 业务规则2人群判定规则
BaseCrowd standard2cduan(StandardConditionRoot root);
// 搜集业务规则中的人群id
List<String> collectCrowdIdFromCondition(StandardConditionRoot condition);
// 搜集业务规则中的标签id
List<String> collectTagIdFromCondition(StandardConditionRoot condition);
}
码表
public class DictConfig {
private final String dictId; // 码表id
private final DictSchema schema; // 码表schema
private final DictDataTypeEnum dataType; // 码表数据类型
}
public class DictSchema {
private final DictSchemaTypeEnum schemaType;// 码表格式枚举
private final StandardDictMeta standardDict;// 基础码表元数据
private final CascadeDictMeta cascadeDict; // 级联码表元数据
}
public class StandardDictMeta {
private List<String> searchFields; // 码表搜索的列private Map<String, String> fieldMapping;// 码表字段与前端字段映射
}
public class CascadeDictMeta {
private List<Map<String, String>> fieldMapping;// 各级码表字段与前端字段映射
}
public interface DictService {
// 新增码表
public void bindDictConfig(DictConfig config);
// 获取码表元数据
public DictConfig getDictConfigById(String id);
// 搜索码表数据
public SlidePageData<DictData> search(DictConfig dictConfig, String matchStr, Integer level, String parentId, Page page);
}
库表结构
ER图
标签
CREATE TABLE `tt_tag_meta` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`tag_id` varchar(255) NOT NULL COMMENT '标签业务id',
`name` varchar(255) NOT NULL COMMENT '标签名称',
`description` varchar(255) NULL COMMENT '描述',
`timeliness_flag` tinyint NOT NULL COMMENT '标签时效性: 0:离线 1:实时',
`schema_type` tinyint NOT NULL COMMENT '标签类型: 1原子标签 2组合标签',
`schema` json NOT NULL COMMENT '标签schema',
`dict_config` json NOT NULL COMMENT '码表配置',
`created_at` timestamp NULL COMMENT '创建时间',
`updated_at` timestamp NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY (`tag_id`)
) ENGINE=InnoDB
CREATE TABLE `tt_tag_view` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`tag_id` varchar(255) NOT NULL COMMENT '标签业务id',
`value_option` json NOT NULL COMMENT '标签可选值',
`id_value_flag` tinyint NOT NULL COMMENT '标签值是否是id: 0:否 1:是',
`created_at` timestamp NULL COMMENT '创建时间',
`updated_at` timestamp NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY (`tag_id`)
) ENGINE=InnoDB
码表
CREATE TABLE `tt_dict_config` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`dict_id` varchar(255) NOT NULL COMMENT '码表id',
`schema_type` tinyint NOT NULL COMMENT 'schema类型: 1:普通 2:级联',
`schema` json NOT NULL COMMENT '码表schema',
`data_type` tinyint NOT NULL COMMENT 'data类型: 1:公共 2:达人 3:店铺',
`created_at` timestamp NULL COMMENT '创建时间',
`updated_at` timestamp NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY (`dict_id`)
) ENGINE=InnoDB
规则语言
{
"logic":"AND",
"offlineCondition":{
"leafs":[
{
"leafType":"TAG",
"tagCondition":{
"tagId":"FC010822",
"dimConditions":[
{
"values":[
{
"values":[
"0"
],
"operator":"EQUAL"
}
],
"dimCode":"prime"
}
]
},
"crowdCondition":null
},
{
"leafType":"TAG",
"tagCondition":{
"tagId":"FA010071",
"dimConditions":[
{
"values":[
{
"values":[
"18-24"
],
"operator":"EQUAL"
},
{
"values":[
"25-30"
],
"operator":"EQUAL"
},
{
"values":[
"31-35"
],
"operator":"EQUAL"
},
{
"values":[
"36-40"
],
"operator":"EQUAL"
}
],
"dimCode":"prime"
}
]
},
"crowdCondition":null
},
{
"leafType":"TAG",
"tagCondition":{
"tagId":"FA010160",
"dimConditions":[
{
"values":[
{
"values":[
"1"
],
"operator":"EQUAL"
}
],
"dimCode":"prime"
}
]
},
"crowdCondition":null
}
],
"logic":"AND",
"children":[
{
"leafs":[
{
"leafType":"TAG",
"tagCondition":{
"tagId":"FA010804",
"dimConditions":[
{
"values":[
{
"values":[
"认知"
],
"operator":"EQUAL"
},
{
"values":[
"种草"
],
"operator":"EQUAL"
},
{
"values":[
"互动"
],
"operator":"EQUAL"
}
],
"dimCode":"prime"
}
]
},
"crowdCondition":null
},
{
"leafType":"TAG",
"tagCondition":{
"tagId":"FA010796",
"dimConditions":[
{
"values":[
{
"values":[
"种草"
],
"operator":"EQUAL"
},
{
"values":[
"认知"
],
"operator":"EQUAL"
},
{
"values":[
"互动"
],
"operator":"EQUAL"
}
],
"dimCode":"prime"
}
]
},
"crowdCondition":null
}
],
"logic":"OR",
"children":[
]
}
]
},
"realtimeCondition":null
}