Go でDynamoDBを操作するときguregu/dynamoを使うことも多いが、BatchGetが遅い ことがあったのとaws-sdk-go v1に対応していないので、直接aws-sdk-go-v2を使うことにした BatchGetするサンプル BatchGetItemを直接使うサンプルは公式になかったので、PartiQLを使う例を参考にして作ってみた。 aws-doc-sdk-examples/gov2/dynamodb/actions/partiql.go at main · awsdocs/aws-doc-sdk-examples package dynamo import ( "context" "fmt" "os" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue" "github.com/aws/aws-sdk-go-v2/service/dynamodb" "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" awsLogging "github.com/aws/smithy-go/logging" ) type MusicRecord struct { Artist string SongTitle string } // maxBatchGetItems is max size for one BatchGetItem request const maxBatchGetItems = 100 func BatchGet( ctx context.Context, region string, endpoint string, targetTable string, titles []string, ) ([]MusicRecord, error) { // initialize client conf, err := config.LoadDefaultConfig(ctx, config.WithRegion(region), config.WithLogger(awsLogging.NewStandardLogger(os.Stdout)), ) if err != nil { return nil, fmt.Errorf("unable to load SDK config: %w", err) } dynamo := dynamodb.NewFromConfig(conf, func(o *dynamodb.Options) { if endpoint != "" { // set endpoint o.BaseEndpoint = &endpoint } }) // create DynamoDB keys dynamoKeys := make([]map[string]types.AttributeValue, 0) for _, v := range titles { dynamoKeys = append(dynamoKeys, map[string]types.AttributeValue{ "SongTitle": &types.AttributeValueMemberS{Value: v}, }) } chunkedKeys := chunk(dynamoKeys, maxBatchGetItems) responses := make([]map[string]types.AttributeValue, 0) for _, k := range chunkedKeys { // BatchGet value from dynamoDB input := &dynamodb.BatchGetItemInput{ RequestItems: map[string]types.KeysAndAttributes{ targetTable: {Keys: k}, }, } out, err := dynamo.BatchGetItem(ctx, input) if err != nil { return nil, fmt.Errorf("failed in get items: %w", err) } responses = append(responses, out.Responses[targetTable]...) } // unmarshal DynamoDB list items to struct records := []MusicRecord{} if err := attributevalue.UnmarshalListOfMaps(responses, &records); err != nil { return nil, fmt.Errorf("failed in unmarshal records: %w", err) } return records, nil } func chunk[T any](collection []T, chunkSize int) [][]T { if chunkSize <= 0 { panic("Second parameter must be greater than 0") } result := make([][]T, 0) for len(collection) > 0 { if len(collection) < chunkSize { chunkSize = len(collection) } result = append(result, collection[0:chunkSize]) collection = collection[chunkSize:] } return result }