検索インデックスを使用してデータをクエリする場合、定義済みのソート方法を使用するか、ソート方法を指定できます。このようにして、クエリ条件を満たす行は、事前に定義または指定した順序に基づいて返されます。レスポンスに多数の行が含まれている場合は、LimitパラメーターとOffsetパラメーターを設定するか、トークンを使用することで、必要なデータを見つけることができます。
シナリオ
カテゴリ | 方法 | 機能 | シナリオ |
ソート | 検索インデックスの作成時にソート方法を事前に定義する | デフォルトでは、検索インデックスのデータは、IndexSortパラメーターで指定された事前ソート設定に基づいてソートされます。IndexSortパラメーターで指定された事前ソート設定により、クエリ条件を満たす行が返されるデフォルトの順序が決まります。 | |
データをクエリするときにソート方法を指定する | ScoreSortを使用して、BM25ベースのキーワード関連性スコアに基づいてクエリ結果をソートできます。ScoreSortは、全文検索などのシナリオに適しています。 | ||
PrimaryKeySortを使用して、プライマリキー値に基づいてクエリ結果をソートできます。PrimaryKeySortは、データの一意の識別子に基づいてデータをソートする場合に適しています。 | |||
FieldSortを使用して、1つ以上の列の値に基づいてクエリ結果をソートできます。FieldSortは、売上高やページビューなどのプロパティに基づいてデータをソートする場合に適しています。ほとんどの場合、FieldSortは、eコマース、ソーシャルネットワーキング、メディアアセットなどの業界で使用されます。 | |||
GeoDistanceSortを使用して、地理的な場所によってクエリ結果をソートできます。GeoDistanceSortは、特定の場所からの距離に基づいてデータをソートする場合に適しています。ほとんどの場合、GeoDistanceSortは、マッピングや物流などの業界で使用されます。たとえば、場所の周りのレストランを、その場所からの距離に基づいてソートできます。 | |||
ページング | データをクエリするときにページング方法を指定する | レスポンスの行数が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パラメーターの最大値を増やす方法については、検索インデックス機能のSearch操作を呼び出してデータをクエリするときに、limitパラメーターの値を1000に増やすにはどうすればよいですか?を参照してください。
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)
}
}