本文主要为您介绍多元索引的排序方式以及翻页方式。

索引预排序(IndexSort)

多元索引默认按照索引中配置的IndexSort进行排序,IndexSort决定了多元索引查询时默认的返回顺序。

IndexSort默认为主键排序,用户可以在创建多元索引时自定义预排序方式。若未自定义IndexSort,多元索引查询的返回结果会按照主键顺序返回。

说明 含有NESTED类型的索引不支持IndexSort,没有预排序。

查询时指定排序方式

在每次查询时,用户也可以指定排序方式,多元索引支持以下四种排序方式(Sorter)。用户也可以使用多个Sorter,实现先按照某种方式排序,再按照某种方式排序的需求。

  • ScoreSort

    按照分数进行排序,应用在全文索引等有相关性的场景中。

    说明 必须手动设置ScoreSort,索引才能按照相关性打分进行排序,否则会按照索引设置的IndexSort进行排序返回。
    sort字段设置:
    sort = Sort(
        sorters=[ScoreSort(sort_order=SortOrder.DESC)]
    )
    client.search(
        table_name, index_name, SearchQuery(query, sort=sort, limit=100, get_total_count=True), ColumnsToGet(return_type=ColumnReturnType.ALL)
    )
  • PrimaryKeySort

    按照主键排序。

    sort字段设置:
    sort = Sort(
        sorters=[PrimaryKeySort(sort_order=SortOrder.DESC)]
    )
    client.search(
        table_name, index_name, SearchQuery(query, sort=sort, limit=100, get_total_count=True), ColumnsToGet(return_type=ColumnReturnType.ALL)
    ) = PrimaryKeySort(sort_order=SortOrder.DESC)
  • FieldSort

    按照某列进行排序。

    sort字段设置:
    sort = Sort(
        sorters=[FieldSort('l', SortOrder.ASC)]
    )
    
    client.search(
        table_name, index_name, SearchQuery(query, sort=sort, limit=100, get_total_count=True), ColumnsToGet(return_type=ColumnReturnType.ALL)
    )
    nested字段排序:
    sort = Sort(
        sorters=[
            FieldSort(
                'n.nl', 
                sort_order=SortOrder.ASC, 
                nested_filter=NestedFilter('n', RangeQuery('n.nl', range_from=150, range_to=200))
            )
        ]
    )
    client.search(
        table_name, index_name, SearchQuery(query, sort=sort, limit=100, get_total_count=True), ColumnsToGet(return_type=ColumnReturnType.ALL)
    )

    先按照某列排序,再按照另一列排序。

    sort字段设置:
    sort = Sort(
        sorters=[
            FieldSort('a', SortOrder.ASC),
            FieldSort('b', SortOrder.ASC)
        ]
    )
    
    client.search(
        table_name, index_name, SearchQuery(query, sort=sort, limit=100, get_total_count=True), ColumnsToGet(return_type=ColumnReturnType.ALL)
    )
  • GeoDistanceSort

    根据地理点距离进行排序。

    sort字段设置:
    sort = Sort(
        sorters=[GeoDistanceSort('g', ['32.5,116.5', '32.0,116.0'], sort_order=SortOrder.DESC, sort_mode=SortMode.MAX)]
    )
    
    client.search(
        table_name, index_name, SearchQuery(query, sort=sort, limit=100, get_total_count=True), ColumnsToGet(return_type=ColumnReturnType.ALL)
    )    

翻页方式

只有enable_sort_and_agg设置为true的字段才能进行排序,排序方式支持多条件设置。

  • 使用limit和offset
    当需要获取的总条数小于2000行时,可以通过limit和offset进行翻页,limit+offset <= 2000。
    query = RangeQuery('k', 'key100', 'key500', include_lower=False, include_upper=False)
    rows, next_token, total_count, is_all_succeed = client.search(
        table_name, index_name, 
        SearchQuery(query, offset=100, limit=100, get_total_count=True), 
        ColumnsToGet(return_type=ColumnReturnType.ALL)
    )      
  • 使用token进行翻页
    服务端在一次查询之后会返回next_token,用户可以使用next_token继续读取后面的数据,排序方式会跟上一次请求一致(不管是系统默认采用IndexSort排序还是用户自定义排序)。使用Token后不能设置Offset,只能一次一次往后读,即无法跳页。
    query = MatchAllQuery()
    all_rows = []
    next_token = None
    
    while not all_rows or next_token:
        rows, next_token, total_count, is_all_succeed = client.search(table_name, index_name,
            SearchQuery(query, next_token=next_token, limit=100, get_total_count=True),
            columns_to_get=ColumnsToGet(['k', 't', 'g', 'ka', 'la'], ColumnReturnType.SPECIFIED))
        all_rows.extend(rows)
    
    for row in all_rows:
        print row
    
    print 'Total rows:', len(all_rows)