セカンダリインデックスのカスタマイズ
「セカンダリインデックス」に基づいてリストクエリを最適化できます。たとえば、Customer モデルがある場合、デフォルトではカスタマーの id 識別子フィールドに基づいてクエリできますが、accountRepresentativeId に基づくセカンダリインデックスを追加して、特定のアカウント担当者の顧客リストを取得することができます。
セカンダリインデックスは「ハッシュキー」と、オプションで「ソートキー」で構成されています。「ハッシュキー」を使用して厳密な等価性を実行し、「ソートキー」を使用して、より大きい (gt)、以上 (ge)、より小さい (lt)、以下 (le)、等しい (eq)、で始まる、および範囲内の操作を実行します。
export const schema = a.schema({ Customer: a .model({ name: a.string(), phoneNumber: a.phone(), accountRepresentativeId: a.id().required(), }) .secondaryIndexes((index) => [index("accountRepresentativeId")]) .authorization(allow => [allow.publicApiKey()]),});以下のクライアントクエリの例は、accountRepresentativeId に基づいて「Customer」レコードをクエリできるカスタム GraphQL リクエストを作成します。
struct PaginatedList<ModelType: Model>: Decodable { let items: [ModelType] let nextToken: String?}let operationName = "listCustomer8ByAccountRepresentativeId"let document = """query ListCustomer8ByAccountRepresentativeId { \(operationName)(accountRepresentativeId: "\(accountRepresentativeId)") { items { createdAt accountRepresentativeId id name phoneNumber updatedAt } nextToken }}"""
let request = GraphQLRequest<PaginatedList<Customer>>( document: document, responseType: PaginatedList<Customer>.self, decodePath: operationName)
let queriedCustomers = try await Amplify.API.query( request: request).get()Amazon DynamoDB での動作方法を確認する
Amplify は a.model() のデフォルトデータソースとして Amazon DynamoDB テーブルを使用します。キー値データベースの場合、「セカンダリインデックス」でアクセスパターンをモデル化することが重要です。.secondaryIndexes() 修飾子を使用してセカンダリインデックスを設定します。
Amazon DynamoDB はキー値およびドキュメントデータベースで、任意のスケールで 1 桁ミリ秒のパフォーマンスを提供しますが、アクセスパターンで機能させるには、いくつかの先見の明が必要です。DynamoDB クエリ操作は最大 2 つの属性を使用してデータを効率的にクエリできます。クエリに渡される最初のクエリ引数 (ハッシュキー) は厳密な等価性を使用する必要があり、2 番目の属性 (ソートキー) は gt、ge、lt、le、eq、beginsWith、および between を使用できます。DynamoDB は、大部分のアプリケーションに十分強力な様々なアクセスパターンを効果的に実装できます。
セカンダリインデックスにソートキーを追加する
「ソートキー」を定義して、「より大きい」(gt)、「以上」(ge)、「より小さい」(lt)、「以下」(le)、「等しい」(eq)、「で始まる」(beginsWith)、「範囲内」などの柔軟なフィルターのセットをクエリに追加できます。
export const schema = a.schema({ Customer: a .model({ name: a.string(), phoneNumber: a.phone(), accountRepresentativeId: a.id().required(), }) .secondaryIndexes((index) => [ index("accountRepresentativeId") .sortKeys(["name"]), ]) .authorization(allow => [allow.owner()]),});クライアント側では、ハッシュキーとソートキーにちなんで名付けられた新しい listBy... クエリに基づいてカスタム GraphQL リクエストを作成できます。このフィルターを新しいリストクエリの一部として指定できます。
struct PaginatedList<ModelType: Model>: Decodable { let items: [ModelType] let nextToken: String?}let operationName = "listCustomer9ByAccountRepresentativeIdAndName"let document = """query ListCustomer8ByAccountRepresentativeId { \(operationName)(accountRepresentativeId: "\(accountRepresentativeId)", name: {beginsWith: "\(name)"}) { items { accountRepresentativeId createdAt id name phoneNumber updatedAt } nextToken }}"""let request = GraphQLRequest<PaginatedList<Customer>>( document: document, responseType: PaginatedList<Customer>.self, decodePath: operationName)
let queriedCustomers = try await Amplify.API.query( request: request).get()セカンダリインデックスのクエリフィールドをカスタマイズする
queryField() 修飾子を設定して、client.models.<MODEL_NAME>.listBy... の下の自動生成されたクエリ名もカスタマイズできます。
const schema = a.schema({ Customer: a .model({ name: a.string(), phoneNumber: a.phone(), accountRepresentativeId: a.id().required(), }) .secondaryIndexes((index) => [ index("accountRepresentativeId") .queryField("listByRep"), ]) .authorization(allow => [allow.owner()]),});クライアントアプリコードでは、更新されたクエリ名を使用できます。
struct PaginatedList<ModelType: Model>: Decodable { let items: [ModelType] let nextToken: String?}let operationName = "listByRep"let document = """query ListByRep { \(operationName)(accountRepresentativeId: "\(accountRepresentativeId)") { items { accountRepresentativeId createdAt id name phoneNumber updatedAt } nextToken }}"""
let request = GraphQLRequest<PaginatedList<Customer>>( document: document, responseType: PaginatedList<Customer>.self, decodePath: operationName)
let queriedCustomers = try await Amplify.API.query( request: request).get()セカンダリインデックスの名前をカスタマイズする
DynamoDB インデックスの名前をカスタマイズするには、name() 修飾子をオプションで指定できます。
const schema = a.schema({ Customer: a .model({ name: a.string(), phoneNumber: a.phone(), accountRepresentativeId: a.id().required(), }) .secondaryIndexes((index) => [ index("accountRepresentativeId") .name("MyCustomIndexName"), ]) .authorization(allow => [allow.owner()]),});セカンダリインデックスのプロジェクション型をカスタマイズする
.projection() 修飾子を使用してプロジェクション型を指定することで、セカンダリインデックスにプロジェクト (コピー) される属性を制御して、ストレージコストを削減し、クエリパターンを最適化できます。
const schema = a.schema({ Product: a .model({ id: a.id().required(), name: a.string().required(), category: a.string().required(), price: a.float().required(), description: a.string(), inStock: a.boolean().required(), }) .secondaryIndexes((index) => [ // キーのみをプロジェクト - 最小インデックスサイズ index('category').projection('KEYS_ONLY'), // キーに加えてクエリする必要がある特定の属性をプロジェクト index('inStock').projection('INCLUDE', ['name', 'price']), // すべての属性をプロジェクト (デフォルト) index('name').projection('ALL'), ]) .authorization(allow => [allow.publicApiKey()]),});プロジェクション型と使用時期を確認する
DynamoDB は 3 つのプロジェクション型をサポートしています。
- KEYS_ONLY - インデックスと主キーのみをプロジェクト。最小インデックスサイズ、最小ストレージコスト。
- INCLUDE - キーと指定された属性をプロジェクト。ストレージコストとクエリの柔軟性のバランス。
- ALL - すべての属性をプロジェクト。最大限のクエリの柔軟性だが、最高のストレージコスト (デフォルト)。
クエリパターンとストレージコスト要件に基づいて選択します。詳細は、DynamoDB のプロジェクションを参照してください。