すべてのプロダクト
Search
ドキュメントセンター

Tablestore:ソートとページング

最終更新日:Dec 28, 2024

検索インデックスを使用してデータをクエリする場合、定義済みのソート方法を使用するか、ソート方法を指定できます。このようにして、クエリ条件を満たす行は、事前に定義または指定した順序に基づいて返されます。レスポンスに多数の行が含まれている場合は、LimitパラメーターとOffsetパラメーターを設定するか、トークンを使用することで、必要なデータを見つけることができます。

シナリオ

カテゴリ

方法

機能

シナリオ

ソート

検索インデックスの作成時にソート方法を事前に定義する

インデックスの事前ソート (IndexSort)

デフォルトでは、検索インデックスのデータは、IndexSortパラメーターで指定された事前ソート設定に基づいてソートされます。IndexSortパラメーターで指定された事前ソート設定により、クエリ条件を満たす行が返されるデフォルトの順序が決まります。

データをクエリするときにソート方法を指定する

BM25ベースのキーワード関連性スコアに基づくソート (ScoreSort)

ScoreSortを使用して、BM25ベースのキーワード関連性スコアに基づいてクエリ結果をソートできます。ScoreSortは、全文検索などのシナリオに適しています。

プライマリキー値に基づくソート (PrimaryKeySort)

PrimaryKeySortを使用して、プライマリキー値に基づいてクエリ結果をソートできます。PrimaryKeySortは、データの一意の識別子に基づいてデータをソートする場合に適しています。

1つ以上の列の値に基づくソート (FieldSort)

FieldSortを使用して、1つ以上の列の値に基づいてクエリ結果をソートできます。FieldSortは、売上高やページビューなどのプロパティに基づいてデータをソートする場合に適しています。ほとんどの場合、FieldSortは、eコマース、ソーシャルネットワーキング、メディアアセットなどの業界で使用されます。

地理的な場所によるソート (GeoDistanceSort)

GeoDistanceSortを使用して、地理的な場所によってクエリ結果をソートできます。GeoDistanceSortは、特定の場所からの距離に基づいてデータをソートする場合に適しています。ほとんどの場合、GeoDistanceSortは、マッピングや物流などの業界で使用されます。たとえば、場所の周りのレストランを、その場所からの距離に基づいてソートできます。

ページング

データをクエリするときにページング方法を指定する

LimitパラメーターとOffsetパラメーターに基づくページング

レスポンスの行数が100,000未満の場合は、この方法を使用してページにジャンプできます。

トークンに基づくページング

デフォルトでは、トークンを使用すると後方へのページングのみ可能です。ただし、トークンはクエリ中は有効であるため、前のトークンをキャッシュして使用することで前方へのページングも可能です。

インデックスの事前ソート

デフォルトでは、検索インデックスのデータは、IndexSortパラメーターで指定された事前ソート設定に基づいてソートされます。検索インデックスを使用してデータをクエリする場合、IndexSortパラメーターで指定された事前ソート設定により、一致するデータが返されるデフォルトの順序が決まります。

検索インデックスを作成するときに、IndexSortパラメーターを設定することで、事前ソート設定を指定できます。事前ソート設定を指定しない場合、検索インデックスのデータはプライマリキー値でソートされます。

重要
  • 検索インデックスの事前ソート方法として、PrimaryKeySortまたはFieldSortを指定できます。PrimaryKeySortはプライマリキー値でデータをソートし、FieldSortはフィールド値でデータをソートします。

  • Nestedフィールドを含む検索インデックスは、インデックスの事前ソートをサポートしていません。

  • 既存の検索インデックスのIndexSortパラメーターの設定を変更する場合は、検索インデックスのスキーマを動的に変更できます。詳細については、検索インデックスのスキーマを動的に変更するを参照してください。

データをクエリするときにソート方法を指定する

ソートは、EnableSortAndAggパラメーターがtrueに設定されているフィールドに対してのみ有効にできます。

クエリごとにソート方法を指定できます。検索インデックスベースのクエリは、次のソート方法をサポートしています。優先順位に基づいて複数のソート方法を指定することもできます。

ScoreSort

ScoreSortを使用して、BM25ベースのキーワード関連性スコアに基づいてクエリ結果をソートできます。ScoreSortは、全文検索などのシナリオに適しています。

重要

キーワード関連性スコアで一致するデータをソートする前に、ScoreSortのパラメーターを設定する必要があります。設定しない場合、一致するデータは、IndexSortパラメーターで指定された事前ソート設定に基づいてソートされます。

searchQuery := search.NewSearchQuery()
searchQuery.SetSort(&search.Sort{
    []search.Sorter{
        &search.ScoreSort{
            Order: search.SortOrder_DESC.Enum(), // クエリ結果をスコアの降順でソートします。
        },
    },
})

PrimaryKeySort

PrimaryKeySortを使用して、プライマリキー値に基づいてクエリ結果をソートできます。

searchQuery := search.NewSearchQuery()
searchQuery.SetSort(&search.Sort{
    []search.Sorter{
        &search.PrimaryKeySort{
            Order: search.SortOrder_ASC.Enum(),
        },
    },
})

FieldSort

FieldSortを使用して、1つ以上の特定の列の値に基づいてクエリ結果をソートできます。

単一列の値に基づいてクエリ結果をソートする

FieldSortを使用して、特定の列の値に基づいてクエリ結果をソートできます。

// Col_Long列の値に基づいてクエリ結果を降順でソートします。
searchQuery.SetSort(&search.Sort{
    []search.Sorter{
        &search.FieldSort{
            FieldName: "Col_Long",
            Order:     search.SortOrder_DESC.Enum(),
        },
    },
})

複数列の値に基づいてクエリ結果をソートする

2つの列の値に基づいて、特定の順序でクエリ結果をソートし、一致するデータが返される順序を決定することもできます。

searchQuery.SetSort(&search.Sort{
    []search.Sorter{
        &search.FieldSort{
            FieldName: "col1",
            Order:     search.SortOrder_ASC.Enum(),
        },
        &search.FieldSort{
            FieldName: "col2",
            Order:     search.SortOrder_DESC.Enum(),
        },
    },
})

GeoDistanceSort

GeoDistanceSortを使用して、地理的な場所によってクエリ結果をソートできます。

searchQuery.SetSort(&search.Sort{
    []search.Sorter{
        &search.GeoDistanceSort{
            FieldName: "location",   // GEOPOINTフィールドの名前を指定します。
            Points:    []string{"40,-70"}, // 中心点の座標ペアを指定します。
        },
    },
})

ページング方法を指定する

LimitパラメーターとOffsetパラメーターを設定するか、トークンを使用して、レスポンスの行をページングできます。

LimitパラメーターとOffsetパラメーターに基づくページング

レスポンスの行の合計数が100,000未満の場合は、LimitパラメーターとOffsetパラメーターを設定して行をページングできます。LimitパラメーターとOffsetパラメーターの値の合計は、100,000を超えることはできません。Limitパラメーターの最大値は100です。

LimitパラメーターとOffsetパラメーターの値を指定しない場合は、デフォルト値が使用されます。Limitパラメーターのデフォルト値は10です。Offsetパラメーターのデフォルト値は0です。

searchQuery := search.NewSearchQuery()
searchQuery.SetLimit(10)
searchQuery.SetOffset(10) 

トークンに基づくページング

この方法にはページング深度に制限がないため、深いページングにはトークンを使用することをお勧めします。

Tablestoreは、クエリ条件を満たすすべてのデータを読み取ることができない場合、NextTokenを返します。NextTokenを使用して、後続のデータの読み取りを続行できます。

デフォルトでは、トークンを使用すると後方へのページングのみ可能です。ただし、トークンはクエリ中は有効であるため、前のトークンをキャッシュして使用することで前方へのページングも可能です。

重要

NextTokenを永続化する場合、またはNextTokenをフロントエンドページに転送する場合は、Base64を使用してNextTokenを文字列にエンコードできます。トークンは文字列ではありません。string(NextToken)を使用してトークンを文字列にエンコードすると、トークンに関する情報が失われます。

トークンを使用する場合、ソート方法は前のリクエストで使用された方法と同じです。Tablestoreは、デフォルトではIndexSortパラメーターに基づいて、または指定した方法に基づいてデータをソートします。トークンを使用する場合は、ソート方法を指定できません。トークンを使用する場合は、Offsetパラメーターを設定できません。データはページごとに順番に返されます。これにより、クエリが遅くなります。

重要

Nestedフィールドを含む検索インデックスは、IndexSortをサポートしていません。ページングが必要で、Nestedフィールドを含む検索インデックスを使用してデータをクエリする場合は、クエリ条件でソート方法を指定して、指定した順序でデータを返す必要があります。指定しない場合、クエリ条件を満たすデータの一部のみが返されるときに、TablestoreはNextTokenを返しません。

/**
 * トークンを使用してデータをページごとに読み取ります。
 * SearchResponseにNextTokenが含まれている場合は、このトークンを使用して次のクエリを開始できます。
 * NextTokenの値がnilの場合、クエリ条件を満たすすべてのデータが返されます。
 */
func QueryRowsWithToken(client *tablestore.TableStoreClient, tableName string, indexName string) {
    querys := []search.Query{
        &search.MatchAllQuery{},
        &search.TermQuery{
            FieldName: "Col_Keyword",
            Term:      "tablestore",
        },
    }
    for _, query := range querys {
        fmt.Printf("テストクエリ: %#v\n", query)
        searchRequest := &tablestore.SearchRequest{}
        searchRequest.SetTableName(tableName)
        searchRequest.SetIndexName(indexName)
        searchQuery := search.NewSearchQuery()
        searchQuery.SetQuery(query)
        searchQuery.SetLimit(10)
        searchQuery.SetGetTotalCount(true)
        searchRequest.SetSearchQuery(searchQuery)
        searchResponse, err := client.Search(searchRequest)
        if err != nil {
            fmt.Printf("%#v", err)
            return
        }
        rows := searchResponse.Rows
        requestCount := 1
        for searchResponse.NextToken != nil {           
            {  
	              // NextTokenを永続化する場合、またはNextTokenをフロントエンドページに転送する場合は、Base64を使用してNextTokenを文字列にエンコードできます。
	              // トークンは文字列ではありません。string(NextToken)を使用してトークンを文字列にエンコードすると、トークンに関する情報が失われます。
	              tokenAsString := base64.StdEncoding.EncodeToString(searchResponse.NextToken)
	              // 文字列をバイトにデコードします。
	              tokenAsByte, err := base64.StdEncoding.DecodeString(tokenAsString)
	              if err != nil {
		                fmt.Printf("len:%d, %#v",len(tokenAsByte), err)
		                return
	              }
            }
            searchQuery.SetToken(searchResponse.NextToken)
            searchResponse, err = client.Search(searchRequest)
            if err != nil {
                fmt.Printf("%#v", err)
                return
            }
            requestCount++
            for _, r := range searchResponse.Rows {
                rows = append(rows, r)
            }
        }
        fmt.Println("IsAllSuccess: ", searchResponse.IsAllSuccess)
        fmt.Println("TotalCount: ", searchResponse.TotalCount)
        fmt.Println("RowsSize: ", len(rows))
        fmt.Println("RequestCount: ", requestCount)
    }
}