虚拟列

使用虚拟列功能时,您可以通过修改多元索引 schema 或者新建多元索引来实现新字段新数据类型的查询功能,而无需修改表格存储的存储结构及数据。

功能概述

虚拟列功能支持用户在创建多元索引的时候将表中一列映射到多元索引中的虚拟列。新的虚拟列类型可以不同于表中的原始列类型,以便支持用户在不修改表结构和数据的情况下新建一列,新的列可以用于查询加速或者采用不同的分词器。

  • 一个 Text 字段支持不同的分词器

    单个字符串列可以映射到多元索引多个 Text 列,不同 Text 列采用不同的分词,以便满足不同的业务需求。

  • 查询加速

    不对表中数据做清洗和重建,只需要将相应列映射为其他类型,即可在部分场景下提升查询性能。例如数字类型转换为 Keyword 类型可以提高精确查询(TermQuery)的性能,String 类型转换为数字类型可以提高范围查询(RangeQuery)的性能。

注意事项

  • 虚拟列支持不同类型到字符串类型的相互转换,转换规则请参见下表。

    数据表中字段类型

    虚拟列字段类型

    String

    Keyword(含数组)

    String

    FuzzyKeyword(含数组)

    String

    Text(含数组)

    String

    Long(含数组)

    String

    Double(含数组)

    String

    Geo-point(含数组)

    Long

    Keyword

    Long

    FuzzyKeyword

    Long

    Text

    Double

    Keyword

    Double

    FuzzyKeyword

    Double

    Text

  • 虚拟列目前仅支持用在查询语句中,不能用在 ColumnsToGet 返回列值,如果需要返回列值,可以指定返回该虚拟列的原始列。

使用方式

您可以使用控制台或者 SDK 进行虚拟列操作。进行虚拟列操作之前,您需要完成如下准备工作。

  • 使用阿里云账号或者具有表格存储操作权限的 RAM 用户进行操作。如果需要为 RAM 用户授权表格存储操作权限,请参见通过RAM PolicyRAM用户授权进行配置。

    使用 SDK 方式进行操作时,如果当前无可用 AccessKey,则需要为阿里云账号或者 RAM 用户创建 AccessKey。具体操作,请参见创建AccessKey

  • 已创建数据表。具体操作,请参见数据表操作

  • 使用 SDK 方式进行操作时,还需要完成初始化 Client。具体操作,请参见初始化OTSClient

通过控制台操作虚拟列

通过控制台在创建多元索引时指定字段为虚拟列后,您可以使用虚拟列查询数据。

  1. 进入索引管理页签。

    1. 登录表格存储控制台

    2. 在页面上方,选择地域和资源组。

    3. 概览页面,单击实例名称或在操作列单击实例管理

    4. 实例详情页签的数据表列表区域,单击数据表名称或在操作列单击索引管理

  2. 索引管理页签,单击创建多元索引

  3. 创建索引对话框,创建多元索引时指定虚拟列。

    image.png

    1. 系统默认会自动生成索引名,可根据需要输入索引名

    2. 选择Schema生成方式

      • Schema生成方式设置为手动录入时,手动输入字段名,选择字段类型以及设置是否开启数组。

      • Schema生成方式设置为自动生成时,系统会自动将数据表的主键列和属性列作为索引字段,可根据需要选择字段类型以及设置是否开启数组。

      说明

      字段名字段类型需与数据表匹配。数据表字段类型与多元索引字段类型的对应关系请参见基础数据类型及映射

    3. 创建虚拟列。

      重要

      创建虚拟列时,原始字段名必须在数据表中存在,且原始字段的数据类型必须和虚拟列的字段类型相匹配。

      1. 单击添加索引字段

      2. 输入字段名字段类型

      3. 打开字段对应虚拟列的开关,并输入原始字段名

    4. 如果要配置多元索引的路由键、数据生命周期或者预排序方式,请打开高级选项开关,并根据实际修改相应参数。更多信息,请参见创建多元索引

    5. 单击确定

      多元索引创建完成后,在多元索引的操作列,单击索引详情,您可以查看多元索引的索引基本信息、索引计量、路由键、索引字段和预排序等信息。

  4. 使用虚拟列查询数据。

    1. 在多元索引的操作列单击搜索

    2. 查询数据对话框,查询数据。

      image

      1. 系统默认返回所有列,如果需要显示指定属性列,关闭获取所有列并输入需要返回的属性列,多个属性列之间用半角逗号(,)隔开。

      2. 选择索引字段,单击添加,并设置索引字段的查询类型和值。

      3. 系统默认关闭排序功能,如需根据索引字段对返回结果进行排序,打开是否排序开关后,根据需要添加索引字段并配置排序方式。

      4. 系统默认关闭统计功能,如需对指定字段进行数据统计,打开是否统计开关后,根据需要添加要进行统计的字段和配置统计信息。

      5. 单击确定

        符合查询条件的数据会显示在索引管理页签中。

通过 SDK 操作虚拟列

通过 SDK 在创建多元索引时指定字段为虚拟列后,您可以使用虚拟列查询数据。

  1. 创建多元索引时指定虚拟列。

    说明

    关于参数的详细说明,请参见创建多元索引

    以下示例用于创建一个多元索引,多元索引包含 Col_Keyword 和 Col_Long 两列,同时创建虚拟列 Col_Keyword_Virtual_Long 和 Col_Long_Virtual_Keyword。Col_Keyword_Virtual_Long 映射为数据表中 Col_Keyword 列,虚拟列 Col_Long_Virtual_Keyword 映射为数据表中 Col_Long 列。

    private static void createSearchIndex(SyncClient client) {
        CreateSearchIndexRequest request = new CreateSearchIndexRequest();
        //设置数据表名称。
        request.setTableName("<TABLE_NAME>"); 
        //设置多元索引名称。
        request.setIndexName("<SEARCH_INDEX_NAME>"); 
        IndexSchema indexSchema = new IndexSchema();
        indexSchema.setFieldSchemas(Arrays.asList(
            //设置字段名和类型。
            new FieldSchema("Col_Keyword", FieldType.KEYWORD), 
            //设置字段名和类型。
            new FieldSchema("Col_Keyword_Virtual_Long", FieldType.LONG) 
                 //设置字段是否为虚拟列。
                .setVirtualField(true) 
                 //虚拟列对应的数据表中字段。
                .setSourceFieldName("Col_Keyword"), 
            new FieldSchema("Col_Long", FieldType.LONG),
            new FieldSchema("Col_Long_Virtual_Keyword", FieldType.KEYWORD)
                .setVirtualField(true)
                .setSourceFieldName("Col_Long")));
        request.setIndexSchema(indexSchema);
        //调用client创建多元索引。
        client.createSearchIndex(request); 
    }
  2. 使用虚拟列查询数据。

    以下示例用于查询表中 Col_Long_Virtual_Keyword 列的值能够匹配 "1000" 的数据,返回匹配到的总行数和一些匹配成功的行。

    private static void query(SyncClient client) {
        SearchQuery searchQuery = new SearchQuery();
        TermsQuery termsQuery = new TermsQuery(); //设置查询类型为TermsQuery。
        termsQuery.setFieldName("Col_Long_Virtual_Keyword"); //设置要匹配的字段。
        termsQuery.addTerm(ColumnValue.fromString("1000")); //设置要匹配的值。
        searchQuery.setQuery(termsQuery);
        searchQuery.setGetTotalCount(true); //设置返回匹配的总行数。
        SearchRequest searchRequest = new SearchRequest("<TABLE_NAME>", "<SEARCH_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());
    }