本文将向您介绍如何使用推荐过滤功能,实现推荐场景的按需定制,满足用户的特定浏览喜好。
一、背景介绍
在某些猜你喜欢场景当中,用户可能会出于需求或自身喜好与经验,只想要看到属于特定品牌等拥有特定属性的物品,此时可以使用推荐过滤功能,只要在客户端埋点对应选择逻辑,在服务端SDK请求推荐结果时加上要筛选的条件,即可获取到希望返回的指定类型(比如指定类别、标签、城市、作者等等)的物品。
实现场景:
以下为使用场景
例1:
当用户在浏览民宿、酒店时,对地点等属性有硬性需求,此时就可以选择对应需求的tag来筛选推荐结果,让用户可以更加方便快捷的找到心仪的物品。(此功能同样也可适用于行为数据较少的新用户,通过用户自身选择来快速锁定用户喜好。)
例2:
新品活动页面筛选用户喜好品牌的活动产品:
用户在浏览新品推荐的场景时,想要对自己感兴趣的品牌进行过滤筛选。
可以看到,该功能可在部分已有场景(如新品、活动商品)的基础上,叠加用户根据自己喜好选择的过滤条件,形成更加灵活、细分、可自由定制的个性化推荐结果。
二、使用方法
推荐过滤功能目前没有控制台设置页面,因为是在已有推荐场景的基础上增加对物品属性的过滤, 因此需要在请求推荐结果时,以添加参数的形式调用请求推荐结果的接口使用,具体方式为:
将表示过滤规则的JSON字符串经过Base64编码后,将编码结果中的”+”、”/” 、”=”分别替换为”-”、”_” 、”.”,然后将此结果作为filter参数,请求推荐接口即可。
除了要求符合基本格式外,过滤规则中还要求:
总的单值过滤规则不超过10个
组合深度不超过3层(即第3层的所有过滤规则必须都是单值过滤规则)
阿里云对URL的长度有限制,因此编码之后的字符串总长度不能过长,否则可能会引起SDK抛错;
一般来说,只要遵循上述1、2要求,这个长度都不会超过限制。
此处JDK示例位于文章末尾
三、功能详解
推荐过滤功能支持对物品的单个属性字段的单值过滤,也支持对多个属性字段的组合过滤。
单值过滤:
支持的过滤条件有三种类型:
包含/不包含(contain/not_contain),仅支持多值字段(多值字段是指可以用逗号分隔的字符串字段,比如tags, author)
相等/不相等(equal/not_equal,仅支持单值字段(比如item_type, title, city)
类目匹配/类目不匹配(category_match/category_not_match),仅支持类目字段(只有category_path),类目匹配只支持从头开始,比如category_path=1_2_3_4,则只能匹配1、1_2、1_2_3、1_2_3_4,而不能匹配2_3、 3_4、2_3_4)
组合过滤:
对单值过滤或其他组合过滤的结果进行“且/或”的逻辑组合。 目前不同行业支持的推荐过滤字段有所差异,具体支持推荐过滤的字段如下:
电商行业:
单值字段:
item_type,category_level,category_path,weight,cur_price,brand_id,shop_id,source_id
多值字段:
tags
内容行业: 单值字段:
item_type,category_level,category_path,channel,weight,pub_id,source_id,country,city
多值字段:
tags,organization,author
新闻行业: 单值字段:
item_type,category_level,category_path,channel,weight,pub_id,source_id,country,city
多值字段:
tags,organization,author
过滤规则通过一个JSON字符串来表示,JSON格式的过滤规则的具体语法如下: 单值过滤:
{
"cond": "contain" | "not_contain" | "equal" | "not_equal"| "category_match" | "category_not_match", // 要进行的比较操作
"field": "<field_name>", // 要筛选的字段名,如"tags"、"channel"等
"value": "<compare_value>" // 要筛选的目标值,如"军事"、"周星驰"等
}
组合过滤:
{
"join": "and" | "or",
"filters": [
{ 组合过滤规则 | 单值过滤规则 },
{ 组合过滤规则 | 单值过滤规则 },
...
]
}
四、应用实例
例3:
如图,假设当前产品为旅游类电商,场景设置有“出行”、“酒店”等场景,其中“出行”场景中设置了“机票”、“火车票”、“汽车/船票”、“接送/租车”四个类目(category_path)的物品(item)。
用户想要查看“出行”页面下,“接送/租车”类目里的“租车”物品,
用户有额外需求是:能送车上门、是京牌、有倒车雷达,
根据需求,此处需要获取推荐商品的请求为:在“出行_接送/租车”类目下,属于“租车”类(假设用brand_id区分)的商品,但因用户有额外需求,则需要使用到组合过滤功能,来满足用户一定的定制需求。
假设后面三项需求是在物品的tags字段中作为属性存放,则此处的推荐过滤表达式为:
( category_path 类目匹配 “出行_接送/租车 )AND ( brand_id = “租车”) AND
((tags 包含 “送车上门”) OR (tags 包含 “京牌”) OR (tags 包含 “倒车雷达”))
可用如下JSON格式的过滤条件查询:
{
"join": "and",
"filters": [
{
"cond": "contain",
"field": "brand_id",
"value": "租车"
},
{
"cond": "category_match",
"field": "category_path",
"value": "出行_接送/租车"
},
{
"join": "or",
"filters": [{
"cond": "contain",
"field": "tags",
"value": "送车上门"
},
{
"cond": "contain",
"field": "tags",
"value": "京牌"
},
{
"cond": "contain",
"field": "tags",
"value": "倒车雷达"
}]
}]
}
在发送请求时,使用如上的过滤条件即可
SDK调用代码样例
SDK调用代码示例:
@Data
private static abstract class BaseFilterRule {}
@EqualsAndHashCode(callSuper = true)
@Data
private static final class JoinFilterRule extends BaseFilterRule {
String join;
List<BaseFilterRule> filters = new ArrayList<>();
}
@EqualsAndHashCode(callSuper = true)
@Data
private static final class SingleFilterRule extends BaseFilterRule {
String cond;
String field;
String value;
}
public void testRecommendWithFilterDemo() throws ClientException {
JoinFilterRule rootRule = new JoinFilterRule();
rootRule.setJoin("and");
{
JoinFilterRule tagsRule = new JoinFilterRule();
tagsRule.setJoin("or");
{
SingleFilterRule rule = new SingleFilterRule();
rule.setCond("contain");
rule.setField("tags");
rule.setValue("小红书");
tagsRule.getFilters().add(rule);
}
{
SingleFilterRule rule = new SingleFilterRule();
rule.setCond("contain");
rule.setField("tags");
rule.setValue("爆品");
tagsRule.getFilters().add(rule);
}
rootRule.getFilters().add(tagsRule);
}
{
SingleFilterRule rule = new SingleFilterRule();
rule.setCond("equal");
rule.setField("channel");
rule.setValue("美妆");
rootRule.getFilters().add(rule);
}
{
SingleFilterRule rule = new SingleFilterRule();
rule.setCond("not_equal");
rule.setField("category");
rule.setValue("促销品");
rootRule.getFilters().add(rule);
}
{
SingleFilterRule rule = new SingleFilterRule();
rule.setCond("category_match");
rule.setField("category_path");
rule.setValue("女装_裙子");
rootRule.getFilters().add(rule);
}
String filterRuleString = new Gson().toJson(rootRule);
filterRuleString = new String(Base64.getEncoder().encode(filterRuleString.getBytes()));
filterRuleString = filterRuleString.replaceAll("\\+", "-");
filterRuleString = filterRuleString.replaceAll("/", "_");
filterRuleString = filterRuleString.replaceAll("=", ".");
DefaultAcsClient client = createClient();
RecommendRequest request = new RecommendRequest();
request.setInstanceId(instanceId);
request.setSceneId(sceneId);
request.setUserId(userId);
request.putQueryParameter("filter", filterRuleString); // 添加filter参数
request.setReturnCount(2);
request.setAcceptFormat(FormatType.JSON);
RecommendResponse response = client.getAcsResponse(request);
System.out.println(String.format("got %d results", response.getResult().size()));
}