多元索引新增IP类型数据类型,支持对IPv4和IPv6地址进行高效存储和查询,满足日志分析、网络安全、地域定位等场景的IP地址检索需求。
如需使用多元索引IP类型,请加入钉钉群36165029092(表格存储技术交流群-3)群联系表格存储技术支持开通。
工作原理
通过将数据表中的String类型字段映射到多元索引的IP类型即可使用IP类型。IP类型支持精确查询、范围查询和混合查询三种查询方式。通过专门的IP地址索引结构,实现对IPv4、IPv6地址及其变体格式的统一存储和高效检索。
IP格式支持
IP类型支持多种IP地址格式,具体格式说明请参见下表。
| IP地址格式 | 描述 | |
| IPv4 | IPv4格式的IP地址,分为4组十进制数,每组之间通过半角句号(.)分隔。 | 
 
 | 
| IPv6 | IPv6格式的IP地址,分为8组四位十六进制数,每组之间通过半角冒号(:)分隔。 | 
 | 
| IPv6缩写格式 | 支持IPv6地址的标准缩写表示法。 | 
 | 
| IPv4映射的IPv6地址 | IPv4-Mapped IPv6 Address格式,支持以IPv4格式查询。 说明  例如写入时某行的column_ip列值为 | 
 | 
查询场景
IP类型查询支持精确查询(即等值查询)、范围查询和混合查询三种方式,适用于不同的业务场景。
| 查询类型 | 说明 | 实现方式 | 应用场景 | 
| 精确查询 | 查询匹配指定IP地址的数据。 | 使用精确查询时配置具体IP地址 | 
 | 
| 范围查询 | 查询在指定IP范围内的数据。 | 
 | 
 | 
| 混合查询 | 基于IP地址与其他维度组合查询数据。 | 使用组合查询功能 | 
 | 
使用IP类型字段
目前支持通过表格存储Java SDK和Go SDK使用IP类型字段。此处以Java SDK为例介绍,请使用5.17.6及以上版本的表格存储Java SDK。
步骤一:创建包含IP类型的多元索引
在创建多元索引时,将要进行IP查询的String类型字段配置为IP类型。
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),
        // 给Col_Ip这一列设置IP类型的索引
        new FieldSchema("Col_Ip", FieldType.IP).setIndex(true).setEnableSortAndAgg(true)
    ));
    request.setIndexSchema(indexSchema);
    client.createSearchIndex(request);
}步骤二:写入IP数据到数据表
向配置了IP类型索引的字段写入IP地址数据:
private static void putRow(SyncClient client) {
    String[] keywords = { "Router", "Phone", "PC1", "PC2", "Home Bot" };
    for (int i = 0; i < 5; i++) {
        // 构建主键
        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);
        // 添加属性列
        rowPutChange.addColumn("Col_Keyword", ColumnValue.fromString(keywords[i]));
        // 添加属性列,写入IP
        rowPutChange.addColumn("Col_Ip", ColumnValue.fromString("192.168.1." + i));
        client.putRow(new PutRowRequest(rowPutChange));
    }
}步骤三:验证配置效果
- 验证精确IP查询 - /** * 精确IP地址查询,需要精确匹配一个IP地址的时候,请使用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()); }
- 验证IP范围查询 - /** * IP地址范围查询,可以通过在TermQuery中使用CIDR表示法或者使用RangeQuery实现 */ private static void searchIpSegment(SyncClient client) { SearchQuery searchQuery = new SearchQuery(); // 通过CIDR表示法查询IP范围 TermQuery query = QueryBuilders.term("Col_Ip", "192.168.1.1/24").build(); // 或者使用Range查询来查询IP范围 // 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()); }
应用于生产环境
- 范围查询使用建议 - 使用范围查询时指定IP地址范围,建议同时指定IP地址的上边界与下边界。当数据表中IPv4地址和IPv6地址混合存储时,如果查询时仅指定单个边界条件且要查询IPv4地址,则可能会查询到IPv6地址。 
- CIDR表示法推荐 - 对于IP范围查询,推荐使用CIDR表示法(如 - 192.168.1.1/24),相比传统的范围查询方式更加简洁准确,避免边界条件设置错误。