过滤器

表格存储支持在查询数据时使用过滤器在服务端按指定条件进行数据过滤,本文介绍如何在 Java SDK 中使用过滤器。

前提条件

初始化Tablestore Client

过滤器类型

表格存储的过滤器类型包括以下 3 种。

  • 单属性列值过滤器(SingleColumnValueFilter):判断单个属性列的值是否符合条件。

  • 单属性列正则过滤器(SingleColumnValueRegexFilter):将 String 类型的属性列按照指定的正则表达式匹配子字符串后转换成指定的数据类型,再判断是否符合条件。

  • 组合过滤器(CompositeColumnValueFilter):将多个条件组合进行数据过滤。

单属性列值过滤器

public class SingleColumnValueFilter extends ColumnValueFilter

参数说明

名称

类型

说明

operator(必选)

CompareOperator

关系运算符,包括 EQUAL(等于)、NOT_EQUAL(不等于)、GREATER_THAN(大于)、GREATER_EQUAL(大于等于)、LESS_THAN(小于)、LESS_EQUAL(小于等于)。

columnName(必选)

String

判断的属性列名称。

columnValue(必选)

ColumnValue

判断的值。

passIfMissing

boolean

行数据不包含判断的属性列时,是否返回该行,默认值为 true,即返回该行数据。

latestVersionsOnly

boolean

是否只判断最新的数据版本,默认值为 true,即当参考的属性列存在多个数据版本时,只判断最新的数据版本是否符合过滤条件。

示例代码

以下示例代码以范围查询为例查询主键值为 [row1, row3) 的行数据,并在查询后进行过滤,返回 col1 属性列的值等于 val1 的行数据。

public static void singleValueFilterExample(SyncClient client) {
    // 构造查询条件
    RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria("test_table");
    // 设置查询起始主键
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
    rangeRowQueryCriteria.setInclusiveStartPrimaryKey(primaryKeyBuilder.build());
    // 设置查询结束主键,返回结果不包含结束主键
    primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row3"));
    rangeRowQueryCriteria.setExclusiveEndPrimaryKey(primaryKeyBuilder.build());
    // 设置查询版本
    rangeRowQueryCriteria.setMaxVersions(1);

    // 构造过滤器,条件为 col1 == "val1"
    SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter("col1", SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromString("val1"));
    rangeRowQueryCriteria.setFilter(singleColumnValueFilter);

    // 调用 getRange 方法查询数据
    GetRangeRequest getRangeRequest = new GetRangeRequest(rangeRowQueryCriteria);
    GetRangeResponse getRangeResponse = client.getRange(getRangeRequest);

    // 返回结果处理
    System.out.println("* RequestId: " + getRangeResponse.getRequestId());
    System.out.println("* Read CU Cost: " + getRangeResponse.getConsumedCapacity().getCapacityUnit().getReadCapacityUnit());
    System.out.println("* Write CU Cost: " + getRangeResponse.getConsumedCapacity().getCapacityUnit().getWriteCapacityUnit());
    for(Row row : getRangeResponse.getRows())
        System.out.println(row);
}
  • 设置行数据不包含判断的属性列时,不返回该行。

    singleColumnValueFilter.setPassIfMissing(false);
  • 设置判断所有版本的数据,此时只要有一个版本的数据符合条件,即返回该行数据。

    singleColumnValueFilter.setLatestVersionsOnly(false);

单属性列正则过滤器

只有 String 类型的属性列支持使用正则过滤器。

public class SingleColumnValueRegexFilter extends ColumnValueFilter

参数说明

名称

类型

说明

operator(必选)

CompareOperator

关系运算符,包括 EQUAL(等于)、NOT_EQUAL(不等于)、GREATER_THAN(大于)、GREATER_EQUAL(大于等于)、LESS_THAN(小于)、LESS_EQUAL(小于等于)。

columnName(必选)

String

判断的属性列名称。

columnValue(必选)

ColumnValue

判断的值。

regexRule(必选)

OptionalValue<RegexRule>

正则匹配规则,包含以下参数。

  • regex:正则表达式,用于匹配子字符串,长度不能超过 256 个字节。

    • 支持 Perl 正则表达式和单字节正则表达式。

    • 不支持中文正则匹配。

    • 支持分组语法,当正则表达式中包含分组时,将返回第一个匹配的子字符串。例如待匹配列值为 1aaa51bbb5,正则表达式为 1([a-z]+)5,返回结果为 aaa

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

示例代码

以下示例代码以范围查询为例查询主键值为 [row1, row3) 的行数据,并在查询后进行正则匹配过滤,返回 col1 属性列的值满足正则表达式 1([a-z]+)5 且匹配到的子字符串为 aaa 的行数据。

public static void singleRegexFilterExample(SyncClient client) {
    // 构造查询条件
    RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria("test_table");
    // 设置查询起始主键
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
    rangeRowQueryCriteria.setInclusiveStartPrimaryKey(primaryKeyBuilder.build());
    // 设置查询结束主键,返回结果不包含结束主键
    primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row3"));
    rangeRowQueryCriteria.setExclusiveEndPrimaryKey(primaryKeyBuilder.build());
    // 设置查询版本
    rangeRowQueryCriteria.setMaxVersions(1);

    // 构造过滤器,条件为 cast<String>(reg(col1)) == “aaa”
    RegexRule regexRule = new RegexRule("1([a-z]+)5", RegexRule.CastType.VT_STRING);
    SingleColumnValueRegexFilter singleColumnValueRegexFilter = new SingleColumnValueRegexFilter("col1", regexRule, SingleColumnValueRegexFilter.CompareOperator.EQUAL, ColumnValue.fromString("aaa"));
    rangeRowQueryCriteria.setFilter(singleColumnValueRegexFilter);

    // 调用 getRange 方法查询行数据
    GetRangeRequest getRangeRequest = new GetRangeRequest(rangeRowQueryCriteria);
    GetRangeResponse getRangeResponse = client.getRange(getRangeRequest);

    // 返回结果处理
    System.out.println("* RequestId: " + getRangeResponse.getRequestId());
    System.out.println("* Read CU Cost: " + getRangeResponse.getConsumedCapacity().getCapacityUnit().getReadCapacityUnit());
    System.out.println("* Write CU Cost: " + getRangeResponse.getConsumedCapacity().getCapacityUnit().getWriteCapacityUnit());
    for(Row row : getRangeResponse.getRows())
        System.out.println(row);
}

组合过滤器

最多支持 32 个条件的组合。

public class CompositeColumnValueFilter extends ColumnValueFilter

参数说明

名称

类型

说明

type(必选)

LogicOperator

逻辑运算符,包括 NOT(非)、AND(与)、OR(或)。

filters(必选)

List<ColumnValueFilter>

参与逻辑运算的过滤器,包括单属性列值过滤器单属性列正则过滤器,也可以是组合过滤器本身。

示例代码

以下示例代码以范围查询为例查询主键值为 [row1, row3) 的行数据,并使用组合过滤器进行数据过滤。

public static void compositeFilterExample(SyncClient client) {
    // 构造查询条件
    RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria("test_version");
    // 设置查询起始主键
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
    rangeRowQueryCriteria.setInclusiveStartPrimaryKey(primaryKeyBuilder.build());
    // 设置查询结束主键,返回结果不包含结束主键
    primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row3"));
    rangeRowQueryCriteria.setExclusiveEndPrimaryKey(primaryKeyBuilder.build());
    // 设置查询版本
    rangeRowQueryCriteria.setMaxVersions(1);

    // 构造单属性列值过滤器1,条件为 col1 == "val1"
    SingleColumnValueFilter singleColumnValueFilter1 = new SingleColumnValueFilter("col1", SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromString("val1"));
    // 构造单属性列正则过滤器1,条件为 cast<String>(reg(col2)) == "aaa"
    RegexRule regexRule = new RegexRule("1([a-z]+)5", RegexRule.CastType.VT_STRING);
    SingleColumnValueRegexFilter singleColumnValueRegexFilter = new SingleColumnValueRegexFilter("col2", regexRule, SingleColumnValueRegexFilter.CompareOperator.GREATER_EQUAL, ColumnValue.fromString("aaa"));
    // 构造组合过滤器1,条件为 col1 == "val1" or cast<String>(reg(col2)) == "aaa"
    CompositeColumnValueFilter compositeColumnValueFilter1 = new CompositeColumnValueFilter(CompositeColumnValueFilter.LogicOperator.OR);
    compositeColumnValueFilter1.addFilter(singleColumnValueFilter1);
    compositeColumnValueFilter1.addFilter(singleColumnValueRegexFilter);
    // 构造单属性列值过滤器2,条件为 col3 == "val3"
    SingleColumnValueFilter singleColumnValueFilter2 = new SingleColumnValueFilter("col3", SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromString("val3"));
    // 构造组合过滤器2,条件为 组合过滤器1 and 单属性列值过滤器2,即 (col1 == "val1" or cast<String>(reg(col2)) == "aaa") and col3 == "val3"
    CompositeColumnValueFilter compositeColumnValueFilter2 = new CompositeColumnValueFilter(CompositeColumnValueFilter.LogicOperator.AND);
    compositeColumnValueFilter2.addFilter(compositeColumnValueFilter1);
    compositeColumnValueFilter2.addFilter(singleColumnValueFilter2);

    // 查询内容添加过滤器
    rangeRowQueryCriteria.setFilter(compositeColumnValueFilter2);

    // 调用 getRange 方法查询行数据
    GetRangeRequest getRangeRequest = new GetRangeRequest(rangeRowQueryCriteria);
    GetRangeResponse getRangeResponse = client.getRange(getRangeRequest);

    // 返回结果处理
    System.out.println("* RequestId: " + getRangeResponse.getRequestId());
    System.out.println("* Read CU Cost: " + getRangeResponse.getConsumedCapacity().getCapacityUnit().getReadCapacityUnit());
    System.out.println("* Write CU Cost: " + getRangeResponse.getConsumedCapacity().getCapacityUnit().getWriteCapacityUnit());
    for(Row row : getRangeResponse.getRows())
        System.out.println(row);
}

相关文档

读取数据