クライアントで大量のデータをフィルタリングするのは非効率です。Tablestore では、フィルターを構成して、指定された条件に基づいてサーバー上のデータをスクリーニングできます。これにより、ネットワークトラフィックが削減され、クエリのパフォーマンスが向上します。
使用方法
Tablestore は、単一列の値のチェック、正規表現のマッチング、複数条件の組み合わせという 3 種類のフィルターを提供します。クエリリクエストの setFilter メソッドを使用してフィルターインスタンスを設定し、サーバー上でデータをフィルタリングします。これにより、ネットワークのオーバーヘッドが削減され、クエリの効率が向上します。
SingleColumnValueFilter: 単一の属性列の値が指定された条件を満たすかどうかを判断するフィルターです。
SingleColumnValueRegexFilter: 正規表現を使用して String 属性列の部分文字列を照合するフィルターです。このフィルターは、部分文字列を指定されたデータの型に変換し、その値が条件を満たすかどうかをチェックします。
CompositeColumnValueFilter: 複数の条件を組み合わせてデータをフィルタリングするフィルターです。
単一列の値フィルター
public class SingleColumnValueFilter extends ColumnValueFilter単一列の値の正規表現フィルター
String 属性列のみが正規表現フィルターをサポートします。
public class SingleColumnValueRegexFilter extends ColumnValueFilter複合フィルター
このフィルターは、最大 32 個の条件の組み合わせをサポートします。
public class CompositeColumnValueFilter extends ColumnValueFilterサンプルコード
コードを実行する前に、TABLESTORE_ACCESS_KEY_ID および TABLESTORE_ACCESS_KEY_SECRET 環境変数を設定して、アクセス資格情報を構成する必要があります。
単一列の値フィルター
次のサンプルコードは、プライマリキーの値が [row1, row3) の範囲にある行に対して範囲クエリを実行する方法を示しています。次に、コードは結果をフィルタリングして、col1 属性が val1 に等しい行のみを返します。
import com.alicloud.openservices.tablestore.SyncClient;
import com.alicloud.openservices.tablestore.core.ResourceManager;
import com.alicloud.openservices.tablestore.core.auth.CredentialsProvider;
import com.alicloud.openservices.tablestore.core.auth.DefaultCredentialProvider;
import com.alicloud.openservices.tablestore.core.auth.DefaultCredentials;
import com.alicloud.openservices.tablestore.core.auth.V4Credentials;
import com.alicloud.openservices.tablestore.model.Column;
import com.alicloud.openservices.tablestore.model.ColumnValue;
import com.alicloud.openservices.tablestore.model.GetRangeRequest;
import com.alicloud.openservices.tablestore.model.GetRangeResponse;
import com.alicloud.openservices.tablestore.model.PrimaryKeyBuilder;
import com.alicloud.openservices.tablestore.model.PrimaryKeyValue;
import com.alicloud.openservices.tablestore.model.RangeRowQueryCriteria;
import com.alicloud.openservices.tablestore.model.Row;
import com.alicloud.openservices.tablestore.model.filter.SingleColumnValueFilter;
public class SingleValueFilter {
public static void main(String[] args) {
// 環境変数からアクセス資格情報を取得します。TABLESTORE_ACCESS_KEY_ID と TABLESTORE_ACCESS_KEY_SECRET を設定する必要があります。
final String accessKeyId = System.getenv("TABLESTORE_ACCESS_KEY_ID");
final String accessKeySecret = System.getenv("TABLESTORE_ACCESS_KEY_SECRET");
// TODO: インスタンス情報に基づいて次の構成を変更します。
final String region = "cn-hangzhou"; // インスタンスが存在するリージョンの ID (例: "cn-hangzhou")。
final String instanceName = "your_instance_name"; // インスタンスの名前。
final String endpoint = "your_endpoint"; // インスタンスのエンドポイント。
SyncClient client = null;
try {
// 資格情報を作成します。
DefaultCredentials credentials = new DefaultCredentials(accessKeyId, accessKeySecret);
V4Credentials credentialsV4 = V4Credentials.createByServiceCredentials(credentials, region);
CredentialsProvider provider = new DefaultCredentialProvider(credentialsV4);
// クライアントインスタンスを作成します。
client = new SyncClient(endpoint, provider, instanceName, null, new ResourceManager(null, null));
// クエリ条件を作成します。
// TODO: テーブル名を変更します。
RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria("test_table");
// 開始プライマリキーを設定します。
// TODO: プライマリキーの名前と値を変更します。
PrimaryKeyBuilder startKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startKeyBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
rangeRowQueryCriteria.setInclusiveStartPrimaryKey(startKeyBuilder.build());
// 終了プライマリキーを設定します。結果には終了プライマリキーは含まれません。
// TODO: プライマリキーの名前と値を変更します。
PrimaryKeyBuilder endKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endKeyBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row3"));
rangeRowQueryCriteria.setExclusiveEndPrimaryKey(endKeyBuilder.build());
// クエリするバージョン数を設定します。
rangeRowQueryCriteria.setMaxVersions(1);
// 条件 col1 == "val1" でフィルターを作成します。
// TODO: フィルターフィールドと値を変更します。
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("Query completed. Result statistics:");
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());
// クエリ結果を出力します。
if (getRangeResponse.getRows() != null && !getRangeResponse.getRows().isEmpty()) {
System.out.println("Found " + getRangeResponse.getRows().size() + " rows that meet the condition:");
for (Row row : getRangeResponse.getRows()) {
// プライマリキー情報を取得して出力します。
// TODO: プライマリキーのデータの型に基づいてこれを変更します。
String primaryKeyInfo = row.getPrimaryKey().toString();
System.out.println("- Primary Key: " + primaryKeyInfo);
// 行のすべての属性列を走査して出力します。MaxVersions が 1 の場合、各列は最新バージョンです。
if (row.getColumns() != null && row.getColumns().length > 0) {
System.out.println(" Attribute Columns:");
for (Column column : row.getColumns()) {
// 列名、値、タイムスタンプを出力します。
String columnName = column.getName();
// TODO: 属性列のデータの型に基づいてこれを変更します。
String columnValue = column.getValue().toString();
long timestamp = column.getTimestamp();
System.out.println(
String.format(" - %s: %s (Version Timestamp: %d)", columnName, columnValue, timestamp)
);
}
} else {
System.out.println(" (This row has no attribute columns)");
}
}
} else {
System.out.println("No data found that meets the filter condition.");
}
System.out.println("Filter query operation completed.");
} catch (Exception e) {
System.err.println("Query failed. Details:");
e.printStackTrace();
} finally {
// クライアントをシャットダウンします。
if (client != null) {
client.shutdown();
}
}
}
}単一列の値の正規表現フィルター
次のサンプルコードは、プライマリキーの値が [row1, row3) の範囲にある行に対して範囲クエリを実行する方法を示しています。次に、コードは正規表現を使用して結果をフィルタリングし、col1 属性が正規表現 1([a-z]+)5 に一致し、一致した部分文字列が aaa である行を返します。
import com.alicloud.openservices.tablestore.SyncClient;
import com.alicloud.openservices.tablestore.core.ResourceManager;
import com.alicloud.openservices.tablestore.core.auth.CredentialsProvider;
import com.alicloud.openservices.tablestore.core.auth.DefaultCredentialProvider;
import com.alicloud.openservices.tablestore.core.auth.DefaultCredentials;
import com.alicloud.openservices.tablestore.core.auth.V4Credentials;
import com.alicloud.openservices.tablestore.model.Column;
import com.alicloud.openservices.tablestore.model.ColumnValue;
import com.alicloud.openservices.tablestore.model.GetRangeRequest;
import com.alicloud.openservices.tablestore.model.GetRangeResponse;
import com.alicloud.openservices.tablestore.model.PrimaryKeyBuilder;
import com.alicloud.openservices.tablestore.model.PrimaryKeyValue;
import com.alicloud.openservices.tablestore.model.RangeRowQueryCriteria;
import com.alicloud.openservices.tablestore.model.Row;
import com.alicloud.openservices.tablestore.model.filter.RegexRule;
import com.alicloud.openservices.tablestore.model.filter.SingleColumnValueRegexFilter;
public class SingleValueRegexFilter {
public static void main(String[] args) {
// 環境変数からアクセス資格情報を取得します。TABLESTORE_ACCESS_KEY_ID と TABLESTORE_ACCESS_KEY_SECRET を設定する必要があります。
final String accessKeyId = System.getenv("TABLESTORE_ACCESS_KEY_ID");
final String accessKeySecret = System.getenv("TABLESTORE_ACCESS_KEY_SECRET");
// TODO: インスタンス情報に基づいて次の構成を変更します。
final String region = "cn-hangzhou"; // インスタンスが存在するリージョンの ID (例: "cn-hangzhou")。
final String instanceName = "your_instance_name"; // インスタンスの名前。
final String endpoint = "your_endpoint"; // インスタンスのエンドポイント。
SyncClient client = null;
try {
// 資格情報を作成します。
DefaultCredentials credentials = new DefaultCredentials(accessKeyId, accessKeySecret);
V4Credentials credentialsV4 = V4Credentials.createByServiceCredentials(credentials, region);
CredentialsProvider provider = new DefaultCredentialProvider(credentialsV4);
// クライアントインスタンスを作成します。
client = new SyncClient(endpoint, provider, instanceName, null, new ResourceManager(null, null));
// クエリ条件を作成します。
// TODO: テーブル名を変更します。
RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria("test_table");
// 開始プライマリキーを設定します。
// TODO: プライマリキーの名前と値を変更します。
PrimaryKeyBuilder startKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startKeyBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
rangeRowQueryCriteria.setInclusiveStartPrimaryKey(startKeyBuilder.build());
// 終了プライマリキーを設定します。結果には終了プライマリキーは含まれません。
// TODO: プライマリキーの名前と値を変更します。
PrimaryKeyBuilder endKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endKeyBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row3"));
rangeRowQueryCriteria.setExclusiveEndPrimaryKey(endKeyBuilder.build());
// クエリするバージョン数を設定します。
rangeRowQueryCriteria.setMaxVersions(1);
// 条件 cast<String>(reg(col1)) == "aaa" で正規表現フィルターを作成します。
// TODO: 正規表現、フィルターフィールド、および一致する値を変更します。
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("Regex filter query completed. Result statistics:");
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());
// クエリ結果を出力します。
if (getRangeResponse.getRows() != null && !getRangeResponse.getRows().isEmpty()) {
System.out.println("Found " + getRangeResponse.getRows().size() + " rows that meet the regex filter condition:");
for (Row row : getRangeResponse.getRows()) {
// プライマリキー情報を取得して出力します。
// TODO: プライマリキーのデータの型に基づいてこれを変更します。
String primaryKeyInfo = row.getPrimaryKey().toString();
System.out.println("- Primary Key: " + primaryKeyInfo);
// 行のすべての属性列を走査して出力します。MaxVersions が 1 の場合、各列は最新バージョンです。
if (row.getColumns() != null && row.getColumns().length > 0) {
System.out.println(" Attribute Columns:");
for (Column column : row.getColumns()) {
// 列名、値、タイムスタンプを出力します。
String columnName = column.getName();
// TODO: 属性列のデータの型に基づいてこれを変更します。
String columnValue = column.getValue().toString();
long timestamp = column.getTimestamp();
System.out.println(
String.format(" - %s: %s (Version Timestamp: %d)", columnName, columnValue, timestamp)
);
}
} else {
System.out.println(" (This row has no attribute columns)");
}
}
} else {
System.out.println("No data found that meets the regex filter condition.");
}
System.out.println("Regex filter query operation completed.");
} catch (Exception e) {
System.err.println("Regex filter query failed. Details:");
e.printStackTrace();
} finally {
// クライアントをシャットダウンします。
if (client != null) {
client.shutdown();
}
}
}
}複合フィルター
次のサンプルコードは、プライマリキーの値が [row1, row3) の範囲にある行に対して範囲クエリを実行し、複合フィルターを使用してデータをフィルタリングする方法を示しています。
import com.alicloud.openservices.tablestore.SyncClient;
import com.alicloud.openservices.tablestore.core.ResourceManager;
import com.alicloud.openservices.tablestore.core.auth.CredentialsProvider;
import com.alicloud.openservices.tablestore.core.auth.DefaultCredentialProvider;
import com.alicloud.openservices.tablestore.core.auth.DefaultCredentials;
import com.alicloud.openservices.tablestore.core.auth.V4Credentials;
import com.alicloud.openservices.tablestore.model.Column;
import com.alicloud.openservices.tablestore.model.ColumnValue;
import com.alicloud.openservices.tablestore.model.GetRangeRequest;
import com.alicloud.openservices.tablestore.model.GetRangeResponse;
import com.alicloud.openservices.tablestore.model.PrimaryKeyBuilder;
import com.alicloud.openservices.tablestore.model.PrimaryKeyValue;
import com.alicloud.openservices.tablestore.model.RangeRowQueryCriteria;
import com.alicloud.openservices.tablestore.model.Row;
import com.alicloud.openservices.tablestore.model.filter.CompositeColumnValueFilter;
import com.alicloud.openservices.tablestore.model.filter.RegexRule;
import com.alicloud.openservices.tablestore.model.filter.SingleColumnValueFilter;
import com.alicloud.openservices.tablestore.model.filter.SingleColumnValueRegexFilter;
public class CompositeFilter {
public static void main(String[] args) {
// 環境変数からアクセス資格情報を取得します。TABLESTORE_ACCESS_KEY_ID と TABLESTORE_ACCESS_KEY_SECRET を設定する必要があります。
final String accessKeyId = System.getenv("TABLESTORE_ACCESS_KEY_ID");
final String accessKeySecret = System.getenv("TABLESTORE_ACCESS_KEY_SECRET");
// TODO: インスタンス情報に基づいて次の構成を変更します。
final String region = "cn-hangzhou"; // インスタンスが存在するリージョンの ID (例: "cn-hangzhou")。
final String instanceName = "your_instance_name"; // インスタンスの名前。
final String endpoint = "your_endpoint"; // インスタンスのエンドポイント。
SyncClient client = null;
try {
// 資格情報を作成します。
DefaultCredentials credentials = new DefaultCredentials(accessKeyId, accessKeySecret);
V4Credentials credentialsV4 = V4Credentials.createByServiceCredentials(credentials, region);
CredentialsProvider provider = new DefaultCredentialProvider(credentialsV4);
// クライアントインスタンスを作成します。
client = new SyncClient(endpoint, provider, instanceName, null, new ResourceManager(null, null));
// クエリ条件を作成します。
// TODO: テーブル名を変更します。
RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria("test_table");
// 開始プライマリキーを設定します。
// TODO: プライマリキーの名前と値を変更します。
PrimaryKeyBuilder startKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startKeyBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
rangeRowQueryCriteria.setInclusiveStartPrimaryKey(startKeyBuilder.build());
// 終了プライマリキーを設定します。結果には終了プライマリキーは含まれません。
// TODO: プライマリキーの名前と値を変更します。
PrimaryKeyBuilder endKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endKeyBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row3"));
rangeRowQueryCriteria.setExclusiveEndPrimaryKey(endKeyBuilder.build());
// クエリするバージョン数を設定します。
rangeRowQueryCriteria.setMaxVersions(1);
// 条件 col1 == "val1" で SingleColumnValueFilter 1 を作成します。
// TODO: フィルターフィールドと値を変更します。
SingleColumnValueFilter singleColumnValueFilter1 = new SingleColumnValueFilter("col1", SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromString("val1"));
// 条件 cast<String>(reg(col2)) >= "aaa" で SingleColumnValueRegexFilter 1 を作成します。
// TODO: 正規表現、フィールド名、および比較値を変更します。
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"));
// 条件 col1 == "val1" OR cast<String>(reg(col2)) >= "aaa" で CompositeColumnValueFilter 1 を作成します。
CompositeColumnValueFilter compositeColumnValueFilter1 = new CompositeColumnValueFilter(CompositeColumnValueFilter.LogicOperator.OR);
compositeColumnValueFilter1.addFilter(singleColumnValueFilter1);
compositeColumnValueFilter1.addFilter(singleColumnValueRegexFilter);
// 条件 col3 == "val3" で SingleColumnValueFilter 2 を作成します。
// TODO: フィルターフィールドと値を変更します。
SingleColumnValueFilter singleColumnValueFilter2 = new SingleColumnValueFilter("col3", SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromString("val3"));
// 条件 CompositeColumnValueFilter 1 AND SingleColumnValueFilter 2 で CompositeColumnValueFilter 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("Query completed. Result statistics:");
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());
// クエリ結果を出力します。
if (getRangeResponse.getRows() != null && !getRangeResponse.getRows().isEmpty()) {
System.out.println("Found " + getRangeResponse.getRows().size() + " rows that meet the condition:");
for (Row row : getRangeResponse.getRows()) {
// プライマリキー情報を取得して出力します。
// TODO: プライマリキーのデータの型に基づいてこれを変更します。
String primaryKeyInfo = row.getPrimaryKey().toString();
System.out.println("- Primary Key: " + primaryKeyInfo);
// 行のすべての属性列を走査して出力します。MaxVersions が 1 の場合、各列は最新バージョンです。
if (row.getColumns() != null && row.getColumns().length > 0) {
System.out.println(" Attribute Columns:");
for (Column column : row.getColumns()) {
// 列名、値、タイムスタンプを出力します。
String columnName = column.getName();
// TODO: 属性列のデータの型に基づいてこれを変更します。
String columnValue = column.getValue().toString();
long timestamp = column.getTimestamp();
System.out.println(
String.format(" - %s: %s (Version Timestamp: %d)", columnName, columnValue, timestamp)
);
}
} else {
System.out.println(" (This row has no attribute columns)");
}
}
} else {
System.out.println("No data found that meets the filter condition.");
}
System.out.println("Composite filter query operation completed.");
} catch (Exception e) {
System.err.println("Query failed. Details:");
e.printStackTrace();
} finally {
// クライアントをシャットダウンします。
if (client != null) {
client.shutdown();
}
}
}
}列が存在しない場合のフィルタリング動作
setPassIfMissing メソッドを使用して、評価対象の属性列が行に含まれていない場合にその行を返すかどうかを指定します。
// 評価対象の属性列が行に含まれていない場合は、その行を返しません。
singleColumnValueFilter.setPassIfMissing(false);履歴バージョンデータのフィルタリング
setLatestVersionsOnly メソッドを使用して、すべてのデータバージョンを評価するかどうかを指定します。すべてのバージョンを評価することを選択した場合、いずれかのバージョンが条件を満たしていれば、その行が返されます。
// すべてのデータバージョンを評価します。
singleColumnValueFilter.setLatestVersionsOnly(false);