过滤器

更新时间:
复制 MD 格式

Java SDK 在服务端按列值筛选行,或按位置截取返回的属性列,减少返回客户端的数据量。

前提条件

安装 Tablestore Java SDK并初始化客户端。

功能说明

过滤器在服务端读取数据后执行筛选,只将符合条件的行返回给客户端。筛选发生在数据读取之后,不影响实际读取的行数,但可减少网络传输的数据量

通过查询条件(SingleRowQueryCriteriaRangeRowQueryCriteriaMultiRowQueryCriteriaRangeIteratorParameter)的 setFilter 方法设置过滤器。过滤器类型包括:

  • SingleColumnValueFilter:单属性列值过滤器。判断单个属性列的值是否符合关系运算条件。

  • SingleColumnValueRegexFilter:单属性列正则过滤器。对 String 类型的属性列按正则提取子字符串后转换数据类型,再按关系运算判断。

  • CompositeColumnValueFilter:组合过滤器。用逻辑运算符(AND / OR / NOT)组合多个过滤器,最多支持 32 个条件

  • ColumnPaginationFilter:列分页过滤器。按偏移量和返回数量截取属性列,不判断列值。

new SingleColumnValueFilter(columnName, operator, columnValue)
new SingleColumnValueRegexFilter(columnName, regexRule, operator, columnValue)
new CompositeColumnValueFilter(logicOperator)
new ColumnPaginationFilter(limit, offset)

以下示例从数据表 filter_demo 中读取 col1 等于 val1 的行。

RangeRowQueryCriteria criteria = new RangeRowQueryCriteria("filter_demo");

PrimaryKeyBuilder startBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
criteria.setInclusiveStartPrimaryKey(startBuilder.build());

PrimaryKeyBuilder endBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
criteria.setExclusiveEndPrimaryKey(endBuilder.build());

criteria.setMaxVersions(1);

// 构造过滤器:col1 == "val1"
SingleColumnValueFilter filter = new SingleColumnValueFilter(
        "col1",
        SingleColumnValueFilter.CompareOperator.EQUAL,
        ColumnValue.fromString("val1"));
criteria.setFilter(filter);

GetRangeResponse response = client.getRange(new GetRangeRequest(criteria));
System.out.println("Matched rows: " + response.getRows().size());

参数说明

单列值过滤器

SingleColumnValueFilter 的构造方法包含以下参数。

名称

类型

说明

columnName(必选)

String

待判断的属性列名称。

operator(必选)

CompareOperator

关系运算符,取值包括:

  • EQUAL(等于)

  • NOT_EQUAL(不等于)

  • GREATER_THAN(大于)

  • GREATER_EQUAL(大于等于)

  • LESS_THAN(小于)

  • LESS_EQUAL(小于等于)

columnValue(必选)

ColumnValue

比较判断的值。

passIfMissing(可选)

boolean

行不包含目标属性列时,是否返回该行。默认 true,即仍返回该行。

设置为 false 时,不包含该属性列的行不会返回。

latestVersionsOnly(可选)

boolean

是否只判断最新的数据版本。默认 true(只判断最新版本)。

设置为 false 时,任意版本符合条件即返回该行。

正则过滤器

SingleColumnValueRegexFilter 的构造方法包含以下参数。设置正则规则时,目标属性列必须为 String 类型。

名称

类型

说明

columnName(必选)

String

待判断的属性列名称。设置 regexRule 时,该列必须为 String 类型。

regexRule(可选)

RegexRule

正则匹配规则。设置后,先从字符串列值中提取子字符串并转换类型,再执行比较;不设置时直接判断原列值。包含以下参数:

  • regex:正则表达式,用于匹配子字符串,长度不超过 256 字节。支持 Perl 正则和单字节正则;不支持中文匹配;支持分组语法(含分组时返回第一个匹配的子字符串,例如待匹配列值 1aaa51bbb5、正则 1([a-z]+)5,返回 aaa)。

  • castType:子字符串转换的类型,取值 VT_INTEGER(整型)、VT_DOUBLE(双精度浮点型)、VT_STRING(字符串)。

operator(必选)

CompareOperator

判断方式。支持 EQUALNOT_EQUALGREATER_THANGREATER_EQUALLESS_THANLESS_EQUALEXISTNOT_EXIST

columnValue(可选)

ColumnValue

比较值。使用六种关系运算符时必选;使用 EXISTNOT_EXIST 时不设置。设置 regexRule 时,值类型应与 castType 一致。

latestVersionsOnly(可选)

boolean

是否只判断属性列的最新版本。默认值为 true;设置为 false 时,只要任一版本符合条件即返回该行。

组合过滤器

CompositeColumnValueFilter 的构造方法和子过滤器列表包含以下参数。通过 addFilter() 添加子过滤器,最多支持 32 个条件

名称

类型

说明

type(必选)

LogicOperator

逻辑运算符,取值包括:

  • AND(与),至少添加两个子过滤器。

  • OR(或),至少添加两个子过滤器。

  • NOT(非),只能添加一个子过滤器。

filters(必选)

List<ColumnValueFilter>

参与逻辑运算的子过滤器,通过 addFilter() 添加。可以是 SingleColumnValueFilterSingleColumnValueRegexFilterCompositeColumnValueFilter(支持嵌套)。

属性列分页过滤器

ColumnPaginationFilter 的构造方法包含以下参数。省略 offset 时,其默认值为 0

名称

类型

说明

limit(必选)

int

返回的属性列数量,必须大于 0。

offset(可选)

int

从第几个属性列开始返回,必须大于或等于 0。默认值为 0

场景示例

正则过滤

通过 RegexRule 提取列值中的子字符串后再比较。以下示例对 col2 应用正则 1([a-z]+)5 提取第一个捕获分组,按字符串与 aaa 比较。

RangeRowQueryCriteria criteria = new RangeRowQueryCriteria("filter_demo");

PrimaryKeyBuilder startBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
criteria.setInclusiveStartPrimaryKey(startBuilder.build());

PrimaryKeyBuilder endBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
criteria.setExclusiveEndPrimaryKey(endBuilder.build());

criteria.setMaxVersions(1);

// 正则 "1([a-z]+)5" 提取第一个捕获分组;castType=VT_STRING 按字符串比较
RegexRule regexRule = new RegexRule("1([a-z]+)5", RegexRule.CastType.VT_STRING);
SingleColumnValueRegexFilter filter = new SingleColumnValueRegexFilter(
        "col2",
        regexRule,
        SingleColumnValueRegexFilter.CompareOperator.EQUAL,
        ColumnValue.fromString("aaa"));
criteria.setFilter(filter);

GetRangeResponse response = client.getRange(new GetRangeRequest(criteria));
System.out.println("Matched rows: " + response.getRows().size());

组合过滤

通过 CompositeColumnValueFilter 用逻辑运算符组合多个过滤器,支持嵌套。以下示例构造条件 (col1 == "val1" OR cast<String>(reg(col2)) >= "aaa") AND col3 == "val3"

RangeRowQueryCriteria criteria = new RangeRowQueryCriteria("filter_demo");

PrimaryKeyBuilder startBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
criteria.setInclusiveStartPrimaryKey(startBuilder.build());

PrimaryKeyBuilder endBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
criteria.setExclusiveEndPrimaryKey(endBuilder.build());

criteria.setMaxVersions(1);

// 叶子 1:col1 == "val1"
SingleColumnValueFilter leaf1 = new SingleColumnValueFilter(
        "col1",
        SingleColumnValueFilter.CompareOperator.EQUAL,
        ColumnValue.fromString("val1"));

// 叶子 2:cast<String>(reg(col2)) >= "aaa"
RegexRule regexRule = new RegexRule("1([a-z]+)5", RegexRule.CastType.VT_STRING);
SingleColumnValueRegexFilter leaf2 = new SingleColumnValueRegexFilter(
        "col2",
        regexRule,
        SingleColumnValueRegexFilter.CompareOperator.GREATER_EQUAL,
        ColumnValue.fromString("aaa"));

// OR 组合:leaf1 OR leaf2
CompositeColumnValueFilter orFilter = new CompositeColumnValueFilter(
        CompositeColumnValueFilter.LogicOperator.OR);
orFilter.addFilter(leaf1);
orFilter.addFilter(leaf2);

// 叶子 3:col3 == "val3"
SingleColumnValueFilter leaf3 = new SingleColumnValueFilter(
        "col3",
        SingleColumnValueFilter.CompareOperator.EQUAL,
        ColumnValue.fromString("val3"));

// AND 组合:(leaf1 OR leaf2) AND leaf3
CompositeColumnValueFilter andFilter = new CompositeColumnValueFilter(
        CompositeColumnValueFilter.LogicOperator.AND);
andFilter.addFilter(orFilter);
andFilter.addFilter(leaf3);

criteria.setFilter(andFilter);

GetRangeResponse response = client.getRange(new GetRangeRequest(criteria));
System.out.println("Matched rows: " + response.getRows().size());

处理列缺失和历史版本

通过 setPassIfMissing 控制行不包含目标列时的返回行为;通过 setLatestVersionsOnly 控制是否判断历史版本数据。

SingleColumnValueFilter filter = new SingleColumnValueFilter(
        "col1",
        SingleColumnValueFilter.CompareOperator.EQUAL,
        ColumnValue.fromString("val1"));

// 行不包含 col1 时不返回(默认 true:缺少 col1 时仍返回)
filter.setPassIfMissing(false);
// 判断所有版本,任一版本匹配即返回(默认 true:仅判断最新版本)
filter.setLatestVersionsOnly(false);

criteria.setFilter(filter);

分页返回属性列

通过 ColumnPaginationFilter 从指定偏移量开始返回一定数量的属性列。以下示例跳过第一个属性列,返回其后的两个属性列。

PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
        .addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"))
        .build();

SingleRowQueryCriteria criteria = new SingleRowQueryCriteria("filter_demo", primaryKey);
criteria.setMaxVersions(1);
criteria.setFilter(new ColumnPaginationFilter(2, 1));

GetRowResponse response = client.getRow(new GetRowRequest(criteria));
for (Column column : response.getRow().getColumns()) {
    System.out.println(column.getName());
}