Name:
interface
Value:
Amplify has re-imagined the way frontend developers build fullstack applications. Develop and deploy without the hassle.

Page updated Jul 14, 2025

Customize secondary indexes

You can optimize your list queries based on "secondary indexes". For example, if you have a Customer model, you can query based on the customer's id identifier field by default but you can add a secondary index based on the accountRepresentativeId to get list customers for a given account representative.

A secondary index consists of a "hash key" and, optionally, a "sort key". Use the "hash key" to perform strict equality and the "sort key" for greater than (gt), greater than or equal to (ge), less than (lt), less than or equal to (le), equals (eq), begins with, and between operations.

amplify/data/resource.ts
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()]),
});

The example client query below allows you to query for "Customer" records based on their accountRepresentativeId:

lib/main.dart
import 'package:amplify_api/amplify_api.dart';
import 'package:amplify_flutter/amplify_flutter.dart';
import 'models/ModelProvider.dart';
final request = ModelQueries.list(
Customer.classType,
where: Customer.ACCOUNTREPRESENTATIVEID.eq(YOUR_REP_ID),
);
Review how this works under the hood with Amazon DynamoDB

Amplify uses Amazon DynamoDB tables as the default data source for a.model(). For key-value databases, it is critical to model your access patterns with "secondary indexes". Use the .secondaryIndexes() modifier to configure a secondary index.

Amazon DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale but making it work for your access patterns requires a bit of forethought. DynamoDB query operations may use at most two attributes to efficiently query data. The first query argument passed to a query (the hash key) must use strict equality and the second attribute (the sort key) may use gt, ge, lt, le, eq, beginsWith, and between. DynamoDB can effectively implement a wide variety of access patterns that are powerful enough for the majority of applications.

Add sort keys to secondary indexes

You can define "sort keys" to add a set of flexible filters to your query, such as "greater than" (gt), "greater than or equal to" (ge), "less than" (lt), "less than or equal to" (le), "equals" (eq), "begins with" (beginsWith), and "between" operations.

amplify/data/resource.ts
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()]),
});

The example client query below allows you to query for "Customer" records based on their name AND their accountRepresentativeId:

lib/main.dart
import 'package:amplify_api/amplify_api.dart';
import 'package:amplify_flutter/amplify_flutter.dart';
import 'models/ModelProvider.dart';
final request = ModelQueries.list(
Customer.classType,
where: Customer.ACCOUNTREPRESENTATIVEID.eq(YOUR_REP_ID) & Customer.NAME.beginsWith("Rene"),
);

Customize the query field for secondary indexes

You can also customize the auto-generated query name under client.models.<MODEL_NAME>.listBy... by setting the queryField() modifier.

amplify/data/resource.ts
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()]),
});

In your client app code, you can use the updated query name.

lib/main.dart
import 'package:amplify_api/amplify_api.dart';
import 'package:amplify_flutter/amplify_flutter.dart';
import 'models/ModelProvider.dart';
var accountRepresentativeId = "John";
var operationName = "listByRep";
var document = """
query ListByRep {
$operationName(accountRepresentativeId: "$accountRepresentativeId") {
items {
accountRepresentativeId
createdAt
id
name
phoneNumber
updatedAt
}
nextToken
}
}
""";
final request = GraphQLRequest(
document: document,
variables: {
'accountRepresentativeId': accountRepresentativeId,
'operationName': operationName,
},
);

Customize the name of secondary indexes

To customize the underlying DynamoDB's index name, you can optionally provide the name() modifier.

amplify/data/resource.ts
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()]),
});