Java SDK 在服務端按列值篩選行,或按位置截取返回的屬性列,減少返回用戶端的資料量。
前提條件
安裝 Tablestore Java SDK並初始化用戶端。
功能說明
過濾器在服務端讀取資料後執行篩選,只將合格行返回給用戶端。篩選發生在資料讀取之後,不影響實際讀取的行數,但可減少網路傳輸的資料量。
通過查詢條件(SingleRowQueryCriteria、RangeRowQueryCriteria、MultiRowQueryCriteria 或 RangeIteratorParameter)的 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 |
關係運算子,取值包括:
|
|
columnValue(必選) |
ColumnValue |
比較判斷的值。 |
|
passIfMissing(可選) |
boolean |
行不包含目標屬性列時,是否返回該行。預設 設定為 |
|
latestVersionsOnly(可選) |
boolean |
是否只判斷最新的資料版本。預設 設定為 |
正則過濾器
SingleColumnValueRegexFilter 的構造方法包含以下參數。設定正則規則時,目標屬性列必須為 String 類型。
|
名稱 |
類型 |
說明 |
|
columnName(必選) |
String |
待判斷的屬性列名稱。設定 |
|
regexRule(可選) |
RegexRule |
正則匹配規則。設定後,先從字串列值中提取子字串並轉換類型,再執行比較;不設定時直接判斷原列值。包含以下參數:
|
|
operator(必選) |
CompareOperator |
判斷方式。支援 |
|
columnValue(可選) |
ColumnValue |
比較值。使用六種關係運算子時必選;使用 |
|
latestVersionsOnly(可選) |
boolean |
是否只判斷屬性列的最新版本。預設值為 |
組合過濾器
CompositeColumnValueFilter 的構造方法和子過濾器列表包含以下參數。通過 addFilter() 添加子過濾器,最多支援 32 個條件。
|
名稱 |
類型 |
說明 |
|
type(必選) |
LogicOperator |
邏輯運算子,取值包括:
|
|
filters(必選) |
List<ColumnValueFilter> |
參與邏輯運算的子過濾器,通過 |
屬性列分頁過濾器
ColumnPaginationFilter 的構造方法包含以下參數。省略 offset 時,其預設值為 0。
|
名稱 |
類型 |
說明 |
|
limit(必選) |
int |
返回的屬性列數量,必須大於 0。 |
|
offset(可選) |
int |
從第幾個屬性列開始返回,必須大於或等於 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());
}