# 过滤配置 过滤的配置与召回的配置是类似的。具体的过滤配置定义放在 FilterConfs 。FilterNames 提供分场景(scene) 的配置,每个 scene 对应一组过滤名称。如果场景没有显式的配置,则走 default 场景配置。 FilterConfs 支持曝光过滤(User2ItemExposureFilter), 状态过滤(ItemStateFilter),数量调整(PriorityAdjustCountFilter, AdjustCountFilter)。 ```bash { "FilterConfs" :[ { "Name": "UserExposureFilter", "FilterType": "User2ItemExposureFilter", "MaxItems": 100, "TimeInterval": 172800, "WriteLog": true, "DaoConf":{ "AdapterType": "hologres", "HologresName": "pai-holo", "HologresTableName": "exposure_history" } }, { "Name": "AdjustCountFilter", "FilterType": "AdjustCountFilter", "RetainNum": 400 } ], "FilterNames":{ "default": ["UniqueFilter", "UserExposureFilter", "AdjustCountFilter", "FeedStatusFilter"], "home_feed": ["UniqueFilter", "UserExposureBloomFilter", "AdjustCountFilter", "FeedStatusFilter"] } } ``` ## 曝光过滤 ### Hologres 在召回之后,大部分场景需要有曝光过滤的需求。对于同一个用户,当推荐服务返回推荐条目后,这些条目需要记录下来,再次请求推荐时,会过滤掉之前的推荐条目。我们这里会单独用表来记录请求过的数据。 holo 表定义, 注意这里可以 按照实际的情况设置 time_to_live_in_seconds 。 ```sql BEGIN; CREATE TABLE "exposure_history" ( "uid" text NOT NULL, "item" text NOT NULL, "create_time" int4 NOT NULL ); CALL SET_TABLE_PROPERTY('"exposure_history"', 'orientation', 'column'); CALL SET_TABLE_PROPERTY('"exposure_history"', 'distribution_key', '"uid"'); CALL SET_TABLE_PROPERTY('"exposure_history"', 'clustering_key', '"uid","create_time"'); CALL SET_TABLE_PROPERTY('"exposure_history"', 'segment_key', '"create_time"'); CALL SET_TABLE_PROPERTY('"exposure_history"', 'bitmap_columns', '"uid","item"'); CALL SET_TABLE_PROPERTY('"exposure_history"', 'dictionary_encoding_columns', '"uid","item"'); CALL SET_TABLE_PROPERTY('"exposure_history"', 'time_to_live_in_seconds', '172800'); comment on table "exposure_history" is '曝光记录表'; COMMIT; ``` FilterConf 配置 ```bash { "Name": "UserExposureFilter", "FilterType": "User2ItemExposureFilter", "MaxItems": 100, "TimeInterval": 172800, "WriteLog": true, "DaoConf":{ "AdapterType": "hologres", "HologresName": "pai-holo", "HologresTableName": "exposure_history" } } ``` * Name 是自定义的名称 * FilterType 过滤类型,固定值 User2ItemExposureFilter * MaxItems 获取最近的条目批次数量,相当于 limit ${MaxItems}, MaxItems 这里不是指的具体的 item 数量, 而是批次的概念,也就是说一次推荐请求算作是一次,和一次请求里有多个具体的物料 item 无关 * TimeInterval 按照时间戳取最近的过滤条目。 create_time >= ${current_time - TimeInterval } * WriteLog 是否写入曝光日志。 * DaoConf 曝光表的定义 ## 状态过滤 很多时候,对于召回的数据,需要进行过滤状态。item 的状态有可能会实时变动的,一般会有专有的表存储 item 状态。 此过滤流程需要实时获取 item 状态信息,然后进行过滤。过滤可以有两种方式去做,一个是拼装好 sql 直接去数据库查,另一个就是只是把需要过滤的字段从数据库中取出来,然后在本地进行过滤。对于召回量数据比较大的情况,第二种反而会有更好的性能,并且能降低数据库的压力。 通用配置如下: ```json { "Name": "ItemStateFilter", "FilterType": "ItemStateFilter", "ItemStateDaoConf":{ "AdapterType": "hologres", "HologresName": "", "HologresTableName": "", "ItemFieldName" : "", "WhereClause": "", "SelectFields" :"" }, "FilterParams" :[] } ``` * Name 是自定义的名称 * FilterType 过滤类型,固定值 ItemStateFilter * ItemStateDaoConf 是状态表的配置 * AdapterType 数据源类型,比如 hologres, redis, tablestore * HologresName 数据源名称,当数据源是 hologres 时设置 * HologresTableName 数据表名称 * ItemFieldName 表中,对应 item id 的 字段名称,一般是主键 * WhereClause 过滤条件语句,设置,会采用第一种查询方式,不设置,可以设置 FilterParams 本地的过滤条件进行过滤 * SelectFields 需要获取哪些字段 * FilterParams 本地的过滤条件,支持多种op 一个具体的例子参考如下: ```bash { "Name": "ItemStateFilter", "FilterType": "ItemStateFilter", "ItemStateDaoConf":{ "AdapterType": "hologres", "HologresName": "holo-test", "HologresTableName": "vvarticle.smart_video_status", "ItemFieldName" : "\"smartVideoId\"", "SelectFields" :"\"publicStatus\", state, \"checkStatus\", norec" }, "FilterParams" :[ { "Name" : "publicStatus", "Type" : "int", "Operator" : "equal", "Value" : 0 }, { "Name" : "state", "Type" : "int", "Operator" : "equal", "Value" : 1 }, { "Name" : "checkStatus", "Type" : "int", "Operator" : "not_equal", "Value" : 2 }, { "Name" : "norec", "Type" : "int", "Operator" : "not_equal", "Value" : 1 } ] } ``` FilterParams 中的 Operator 还支持 in, greater , greaterThan , less, lessThan 操作符。 状态过滤也支持TableStore(ots) 存储,通用配置如下: ```bash { "Name": "ItemStateFilter", "FilterType": "ItemStateFilter", "ItemStateDaoConf":{ "AdapterType": "tablestore", "TableStoreName": "", "TableStoreTableName": "", "ItemFieldName" : "", "SelectFields" :"" }, "FilterParams" :[] } ``` ## 数量调整过滤 在召回阶段,一般的数量在 千级别以上,但是在排序(Rank)阶段,会由于性能的因素,会把数量控制在 百级别。那么就需要数量调整,数量调整也包含在过滤阶段,目前提供如下形式的数量调整。 ### AdjustCountFilter 简单的调整数量,把召回数量随机打散,然后保留需要控制的数量。配置如下 ```bash { "Name": "AdjustCountFilter", "FilterType": "AdjustCountFilter", "ShuffleItem": true, "RetainNum": 500 } ``` * Name 是自定义的名称 * FilterType 过滤类型,固定值 AdjustCountFilter * RetainNum 需要保留的召回数量 * ShuffleItem 是否对 item 进行随机排序后再返回, 默认 true。 如果不想改变 item 位置,设置为 false ### PriorityAdjustCountFilter 优先级过滤可以对各路召回进行数量控制,每路召回都会根据召回的 score 进行排序。 ```bash { "Name": "PriorityAdjustCountFilterV5", "FilterType": "PriorityAdjustCountFilter", "AdjustCountConfs" :[ { "RecallName" :"U2IRecallV3V10", "Count" :125, "Type" : "accumulator" }, { "RecallName" :"SwingU2IRecallV3V10", "Count" :250, "Type" : "accumulator" }, { "RecallName" :"VideoVectorRecallV10", "Count" :400, "Type" : "accumulator" }, { "RecallName" :"UserGroupHotRecallV10", "Count" :450, "Type" : "accumulator" }, { "RecallName" :"UserGlobalHotRecallV10", "Count" :500, "Type" : "accumulator" } ] } ``` * Name 是自定义的名称 * FilterType 过滤类型,固定值 PriorityAdjustCountFilter * AdjustCountConfs 具体的数量控制配置 * RecallName 召回源名称 * Count 限制的数量 * Type 限制类型, accumulator 为累加限制。比如 U2IRecallV3V10 数量最多控制在 125, SwingU2IRecallV3V10 最多控制在 250, SwingU2IRecallV3V10 召回数量就是 250 - 125, 当 U2IRecallV3V10 不足 125 时, SwingU2IRecallV3V10 也会尽量补齐到 250 ,依次类推。