Full table scans and range reads return many rows that your application then discards, which wastes bandwidth. Filters evaluate property column values on the server and return only the rows that match your criteria, which reduces network traffic. Tablestore SDK for Java supports single-column comparisons, comparisons on regex-extracted substrings, and logical combinations of multiple conditions.
Prerequisites
Install the Tablestore SDK for Java and initialize the client.
How filters work
A filter runs on the server after each row is read and returns only the rows that match your criteria. Because filtering happens after the read, it does not reduce the number of rows scanned, but it does reduce the volume of data sent over the network.
Attach a filter to a query request by calling its setFilter method. Supported request classes: SingleRowQueryCriteria, RangeRowQueryCriteria, MultiRowQueryCriteria, and RangeIteratorParameter. Tablestore SDK for Java provides three filters:
-
SingleColumnValueFilter: compares the value of one property column against a target value with a relational operator.
-
SingleColumnValueRegexFilter: extracts a substring from a
Stringproperty column with a regular expression, converts it to a target type, and compares it against a target value. -
CompositeColumnValueFilter: combines multiple filters with logical operators (
AND,OR, orNOT). A composite filter supports up to 32 sub-conditions.
The three filters have the following class signatures:
public class SingleColumnValueFilter extends ColumnValueFilter
public class SingleColumnValueRegexFilter extends ColumnValueFilter
public class CompositeColumnValueFilter extends ColumnValueFilter
The following example reads rows from the filter_demo table where the col1 column equals val1. It uses SingleColumnValueFilter, the most common of the three.
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);
// Build the filter: 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());
Parameters
SingleColumnValueFilter
Signature: new SingleColumnValueFilter(columnName, operator, columnValue).
|
Name |
Type |
Description |
|
columnName (required) |
String |
The name of the property column to evaluate. |
|
operator (required) |
CompareOperator |
The relational operator. Valid values:
|
|
columnValue (required) |
ColumnValue |
The value used in the comparison. |
|
passIfMissing (optional) |
boolean |
Whether to return rows that do not contain the target column. Default Set to |
|
latestVersionsOnly (optional) |
boolean |
Whether to evaluate only the latest version of the column. Default Set to |
SingleColumnValueRegexFilter
Signature: new SingleColumnValueRegexFilter(columnName, regexRule, operator, columnValue). Only String property columns support regex filtering.
|
Name |
Type |
Description |
|
columnName (required) |
String |
The name of the property column to evaluate. The column must be of type |
|
regexRule (required) |
RegexRule |
The regex matching rule. It contains two parameters:
|
|
operator (required) |
CompareOperator |
The relational operator. Valid values are the same as for |
|
columnValue (required) |
ColumnValue |
The value used in the comparison. The type must match |
CompositeColumnValueFilter
Signature: new CompositeColumnValueFilter(logicOperator). Add sub-filters by calling addFilter(). A composite filter supports up to 32 sub-conditions.
|
Name |
Type |
Description |
|
type (required) |
LogicOperator |
The logical operator. Valid values:
|
|
filters (required) |
List<ColumnValueFilter> |
The sub-filters combined by the logical operator. Add each sub-filter with |
Examples
Compare a substring extracted with a regular expression
Use RegexRule to extract a substring from a column value, then compare the substring against a target value. The following example applies the regex 1([a-z]+)5 to col1, captures the first group, and compares it against the string 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);
// The regex "1([a-z]+)5" captures the first group; castType=VT_STRING compares the result as a string.
RegexRule regexRule = new RegexRule("1([a-z]+)5", RegexRule.CastType.VT_STRING);
SingleColumnValueRegexFilter filter = new SingleColumnValueRegexFilter(
"col1",
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());
Combine multiple filters with logical operators
Use CompositeColumnValueFilter to combine multiple filters with logical operators. Composite filters can be nested. The following example builds the condition (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);
// Leaf 1: col1 == "val1"
SingleColumnValueFilter leaf1 = new SingleColumnValueFilter(
"col1",
SingleColumnValueFilter.CompareOperator.EQUAL,
ColumnValue.fromString("val1"));
// Leaf 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 combination: leaf1 OR leaf2
CompositeColumnValueFilter orFilter = new CompositeColumnValueFilter(
CompositeColumnValueFilter.LogicOperator.OR);
orFilter.addFilter(leaf1);
orFilter.addFilter(leaf2);
// Leaf 3: col3 == "val3"
SingleColumnValueFilter leaf3 = new SingleColumnValueFilter(
"col3",
SingleColumnValueFilter.CompareOperator.EQUAL,
ColumnValue.fromString("val3"));
// AND combination: (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());
Control evaluation of missing columns and historical versions
Use setPassIfMissing to control whether rows that do not contain the target column are returned, and setLatestVersionsOnly to control whether historical versions are evaluated as well.
SingleColumnValueFilter filter = new SingleColumnValueFilter(
"col1",
SingleColumnValueFilter.CompareOperator.EQUAL,
ColumnValue.fromString("val1"));
// Skip rows that do not contain col1 (default: include such rows).
filter.setPassIfMissing(false);
// Evaluate all versions; return the row if any version matches (default: evaluate only the latest version).
filter.setLatestVersionsOnly(false);
criteria.setFilter(filter);