The IP data type in search indexes stores and queries IPv4 and IPv6 addresses for log analysis, network security, and geo-location scenarios.
To use the IP data type for a search index, and contact Tablestore technical support to enable the feature.
How it works
Map a String field from your data table to the IP type in the search index. The IP data type supports three query methods: term query, range query, and composite query. A specialized IP address index structure provides unified storage and efficient retrieval for IPv4, IPv6, and their variant formats.
Supported IP formats
The IP data type supports the following IP address formats.
|
IP address format |
Description |
|
|
IPv4 |
Standard IPv4 address format: four groups of decimal numbers separated by periods (.). |
|
|
IPv6 |
Standard IPv6 address format: eight groups of four hexadecimal digits separated by colons (:). |
|
|
Abbreviated IPv6 format |
Standard abbreviated notation for IPv6 addresses. |
|
|
IPv4-mapped IPv6 address |
IPv4-mapped IPv6 address format. Supports queries using the IPv4 format. Note
For example, if the value of the |
|
Query scenarios
IP type queries support three methods, each suited for different business scenarios.
|
Query type |
Description |
Implementation |
Use case |
|
Term query |
Matches a specific IP address. |
Specify the target IP address in a term query. |
|
|
Range query |
Matches data within a specified IP address range. |
|
|
|
Composite query |
Combines IP address conditions with other dimensions. |
Use the composite query feature to combine multiple conditions. |
|
Use an IP type field
The Tablestore Java SDK and Go SDK support IP type fields. The following example uses the Java SDK. Use version 5.17.6 or later of the Tablestore Java SDK.
Step 1: Create a search index that contains an IP type
When creating a search index, map the String field for IP queries to the IP type.
private static void createSearchIndex(SyncClient client) {
CreateSearchIndexRequest request = new CreateSearchIndexRequest();
request.setTableName(TABLE_NAME);
request.setIndexName(INDEX_NAME);
IndexSchema indexSchema = new IndexSchema();
indexSchema.setFieldSchemas(Arrays.asList(
new FieldSchema("Col_Keyword", FieldType.KEYWORD).setIndex(true).setEnableSortAndAgg(true),
// Set the index for the Col_Ip column to the IP type.
new FieldSchema("Col_Ip", FieldType.IP).setIndex(true).setEnableSortAndAgg(true)
));
request.setIndexSchema(indexSchema);
client.createSearchIndex(request);
}
Step 2: Write IP data to the data table
Write IP address data to the field configured as the IP type.
private static void putRow(SyncClient client) {
String[] keywords = { "Router", "Phone", "PC1", "PC2", "Home Bot" };
for (int i = 0; i < 5; i++) {
// Build the primary key.
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.fromString("pk1" + i));
PrimaryKey primaryKey = primaryKeyBuilder.build();
RowPutChange rowPutChange = new RowPutChange(TABLE_NAME, primaryKey);
// Add an attribute column.
rowPutChange.addColumn("Col_Keyword", ColumnValue.fromString(keywords[i]));
// Add an attribute column and write the IP address.
rowPutChange.addColumn("Col_Ip", ColumnValue.fromString("192.168.1." + i));
client.putRow(new PutRowRequest(rowPutChange));
}
}
Step 3: Verify the configuration
-
Verify a term IP query
/** * To query for an exact IP address, use TermQuery. */ private static void searchExactIp(SyncClient client) { SearchQuery searchQuery = new SearchQuery(); TermQuery query = QueryBuilders.term("Col_Ip", "192.168.1.1").build(); searchQuery.setQuery(query); searchQuery.setLimit(100); SearchRequest searchRequest = new SearchRequest(TABLE_NAME, INDEX_NAME, searchQuery); SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet(); columnsToGet.setReturnAll(true); searchRequest.setColumnsToGet(columnsToGet); SearchResponse resp = client.search(searchRequest); System.out.println("TotalCount: " + resp.getTotalCount()); System.out.println("Row: " + resp.getRows()); } -
Verify an IP range query
/** * To query for an IP address range, you can use CIDR notation in a TermQuery or use a RangeQuery. */ private static void searchIpSegment(SyncClient client) { SearchQuery searchQuery = new SearchQuery(); // Query for an IP range using CIDR notation. TermQuery query = QueryBuilders.term("Col_Ip", "192.168.1.1/24").build(); // Alternatively, use a RangeQuery to query for an IP range. // RangeQuery query = QueryBuilders.range("Col_Ip").greaterThanOrEqual("192.168.1.0").lessThanOrEqual("192.168.1.255").build(); searchQuery.setQuery(query); searchQuery.setLimit(100); SearchRequest searchRequest = new SearchRequest(TABLE_NAME, INDEX_NAME, searchQuery); SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet(); columnsToGet.setReturnAll(true); searchRequest.setColumnsToGet(columnsToGet); SearchResponse resp = client.search(searchRequest); System.out.println("TotalCount: " + resp.getTotalCount()); System.out.println("Row: " + resp.getRows()); }
Best practices
-
Specify both boundaries in range queries
Always specify both the upper and lower boundaries of the IP address range. If your data table contains both IPv4 and IPv6 addresses, a query with only a single boundary condition for an IPv4 address might return unwanted IPv6 addresses.
-
Prefer CIDR notation
For IP range queries, use CIDR notation such as
192.168.1.1/24. CIDR notation is more concise and accurate than traditional range queries and helps prevent boundary condition errors.