使用二级索引读取数据

表格存储提供了单行读取和范围读取的查询方式用于读取索引表中数据。当返回的属性列在索引表中时,您可以直接读取索引表获取数据,否则请自行反查数据表获取数据。

前提条件

注意事项

  • 索引表只能用于读取数据。

  • 本地二级索引表的第一列主键必须与数据表的第一列主键相同。

  • 当需要返回的属性列不在索引表中时,您需要自行反查数据表来获取数据。

单行读取数据

调用GetRow接口读取一行数据。更多信息,请参见读取单行数据

参数

使用GetRow接口读取索引表中数据时有如下注意事项:

  • table_name需要设置为索引表名称。

  • 由于系统会自动将未出现在索引列中的数据表主键补齐到索引表主键中,所以设置行的主键时,需要同时设置索引表索引列和补齐的数据表主键。

示例

以下示例用于读取索引表中指定主键的行数据。

# 构造主键。第一列主键为definedcol1,值是整数1;第二列主键为pk1,值是整数101;第三列主键为补齐的数据表主键pk2,值是整数11。
# 如果读取本地二级索引中的数据,索引表的第一列主键必须与数据表的第一列主键相同。
primary_key = [('definedcol1', 1), ('pk1', 101), ('pk2', 11)]

# 需要返回的索引表属性列definedcol2和definedcol3。如果columns_to_get为[],则返回索引表的所有属性列。
columns_to_get = ['definedcol2', 'definedcol3']

# 设置过滤器,增加列条件。过滤条件为definedcol2列值不等于1且definedcol3列值等于'test'。
cond = CompositeColumnCondition(LogicalOperator.AND)
cond.add_sub_condition(SingleColumnCondition("definedcol2", 1, ComparatorType.NOT_EQUAL))
cond.add_sub_condition(SingleColumnCondition("definedcol3", 'test', ComparatorType.EQUAL))

try:
    # 调用get_row接口查询数据。
    # 配置索引表名称,最后一个参数值1表示只需要返回一个版本的值。
    consumed, return_row, next_token = client.get_row('<INDEX_NAME>', primary_key, columns_to_get, cond, 1)
    print('Read succeed, consume %s read cu.' % consumed.read)
    print('Value of primary key: %s' % return_row.primary_key)
    print('Value of attribute: %s' % return_row.attribute_columns)
    for att in return_row.attribute_columns:
        # 打印每一列的key、value和version值。
        print('name:%s\tvalue:%s' % (att[0], att[1]))
# 客户端异常,一般为参数错误或者网络异常。
except OTSClientError as e:
    print('get row failed, http_status:%d, error_message:%s' % (e.get_http_status(), e.get_error_message()))
# 服务端异常,一般为参数错误或者流控错误。
except OTSServiceError as e:
    print('get row failed, http_status:%d, error_code:%s, error_message:%s, request_id:%s' % (e.get_http_status(), e.get_error_code(), e.get_error_message(), e.get_request_id()))

范围读取数据

调用GetRange接口读取一个范围内的数据。更多信息,请参见范围读取数据

参数

使用GetRange接口读取索引表中数据时有如下注意事项:

  • table_name需要设置为索引表名称。

  • 由于系统会自动将未出现在索引列中的数据表主键补齐到索引表主键中,所以设置起始主键和结束主键时,需要同时设置索引表索引列和补齐的数据表主键。

示例

以下示例用于读取指定主键范围内的数据。

# 设置范围读的起始主键。如果读取本地二级索引中的数据,索引表的第一列主键必须与数据表的第一列主键相同。
inclusive_start_primary_key = [('definedcol1', 1), ('pk1', INF_MIN), ('pk2', INF_MIN)]

# 设置范围读的结束主键。
exclusive_end_primary_key = [('definedcol1', 5), ('pk1', INF_MAX), ('pk2', INF_MIN)]

# 查询索引表中所有列。
columns_to_get = []

# 每次最多返回90行,如果总共有100个结果,首次查询时指定limit=90,则第一次最多返回90,最少可能返回0个结果,但是next_start_primary_key不为None。
limit = 90

# 设置过滤器,增加列条件。过滤条件为definedcol2列值小于50且definedcol3列值等于'China'。
cond = CompositeColumnCondition(LogicalOperator.AND)
# 如果某行不存在对应列时,您需要配置pass_if_missing参数来确定该行是否满足过滤条件。
# 当不设置pass_if_missing或者设置pass_if_missing为True时,表示当某行不存在该列时,该行满足过滤条件。
# 当设置pass_if_missing为False时,表示当某行不存在该列时,该行不满足过滤条件。
cond.add_sub_condition(SingleColumnCondition("definedcol3", 'China', ComparatorType.EQUAL, pass_if_missing=False))
cond.add_sub_condition(SingleColumnCondition("definedcol2", 50, ComparatorType.LESS_THAN, pass_if_missing=False))

try:
    # 调用get_range接口。
    # 设置索引表名称。
    consumed, next_start_primary_key, row_list, next_token = client.get_range(
        '<INDEX_NAME>', Direction.FORWARD,
        inclusive_start_primary_key, exclusive_end_primary_key,
        columns_to_get,
        limit,
        column_filter=cond,
        max_version=1,
        time_range=(1557125059000, 1557129059000)  # start_time大于等于1557125059000,end_time小于1557129059000。
    )

    all_rows = []
    all_rows.extend(row_list)

    # 当next_start_primary_key不为空时,则继续读取数据。
    while next_start_primary_key is not None:
        inclusive_start_primary_key = next_start_primary_key
        consumed, next_start_primary_key, row_list, next_token = client.get_range(
            '<INDEX_NAME>', Direction.FORWARD,
            inclusive_start_primary_key, exclusive_end_primary_key,
            columns_to_get, limit,
            column_filter=cond,
            max_version=1
        )
        all_rows.extend(row_list)

    # 打印主键和属性列。
    for row in all_rows:
        print(row.primary_key, row.attribute_columns)
    print('Total rows: ', len(all_rows))
# 客户端异常,一般为参数错误或者网络异常。
except OTSClientError as e:
    print('get row failed, http_status:%d, error_message:%s' % (e.get_http_status(), e.get_error_message()))
# 服务端异常,一般为参数错误或者流控错误。
except OTSServiceError as e:
    print('get row failed, http_status:%d, error_code:%s, error_message:%s, request_id:%s' % (e.get_http_status(), e.get_error_code(), e.get_error_message(), e.get_request_id())

常见问题

相关文档

  • 当日常业务中有非主键列查询、多列组合查询、模糊查询等多维查询需求以及求最值、统计行数、数据分组等数据分析需求时,您可以将这些属性作为多元索引中的字段并使用多元索引查询与分析数据。 更多信息,请参见多元索引

  • 如果需要使用SQL查询和分析数据,您可以使用SQL查询功能实现。更多信息,请参见SQL查询