Name:
interface
Value:
Amplify has re-imagined the way frontend developers build fullstack applications. Develop and deploy without the hassle.
Maintenance ModeYou are viewing Amplify Gen 1 documentation. Amplify Gen 1 has entered maintenance mode and will reach end of life on May 1, 2027. New project should use Amplify Gen 2. For existing Gen 1 projects, a migration guide and tooling are available to help you upgrade. Switch to the latest Gen 2 docs →

データアクセスパターン

You are currently viewing the legacy GraphQL Transformer documentation. View latest documentation

DynamoDB ドキュメント(NoSQL データベースでのリレーショナルデータのモデリング)には、DynamoDB でのリレーショナルデータのモデリング最初のステップページから 17 個のアクセスパターンの詳細な例があります。

組織での最も一般的で重要なアクセスパターン
1従業員 ID で従業員の詳細情報を検索
2従業員名で従業員の詳細情報をクエリ
3従業員の電話番号を検索
4顧客の電話番号を検索
5特定の顧客の指定期間内の注文を取得
6指定期間内のすべての顧客の未処理注文を表示
7最近採用されたすべての従業員を表示
8特定の倉庫で働くすべての従業員を検索
9特定の製品の注文中のすべてのアイテムを取得
10すべての倉庫での特定の製品の現在の在庫を取得
11アカウント担当者による顧客を取得
12アカウント担当者と日付による注文を取得
13特定の製品の注文中のすべてのアイテムを取得
14特定の職種を持つすべての従業員を取得
15製品と倉庫による在庫を取得
16製品の総在庫を取得
17注文合計と販売期間でランク付けされたアカウント担当者を取得

この例では、GraphQL、AWS Amplify、GraphQL Transform ライブラリを使用してこれらのデータアクセスパターンをサポートする方法を学びます。この例には以下の型があります:

  • Warehouse
  • Product
  • Inventory
  • Employee
  • AccountRepresentative
  • Customer

次のスキーマは、これらのアクセスパターンをサポートするために必要なキーと接続を紹介しています:

type Order
@model
@key(
name: "byCustomerByStatusByDate"
fields: ["customerID", "status", "date"]
)
@key(name: "byCustomerByDate", fields: ["customerID", "date"])
@key(
name: "byRepresentativebyDate"
fields: ["accountRepresentativeID", "date"]
)
@key(name: "byProduct", fields: ["productID", "id"]) {
id: ID!
customerID: ID!
accountRepresentativeID: ID!
productID: ID!
status: String!
amount: Int!
date: String!
}
type Customer
@model
@key(name: "byRepresentative", fields: ["accountRepresentativeID", "id"]) {
id: ID!
name: String!
phoneNumber: String
accountRepresentativeID: ID!
ordersByDate: [Order] @connection(keyName: "byCustomerByDate", fields: ["id"])
ordersByStatusDate: [Order]
@connection(keyName: "byCustomerByStatusByDate", fields: ["id"])
}
type Employee
@model
@key(
name: "newHire"
fields: ["newHire", "id"]
queryField: "employeesNewHire"
)
@key(
name: "newHireByStartDate"
fields: ["newHire", "startDate"]
queryField: "employeesNewHireByStartDate"
)
@key(name: "byName", fields: ["name", "id"], queryField: "employeeByName")
@key(
name: "byTitle"
fields: ["jobTitle", "id"]
queryField: "employeesByJobTitle"
)
@key(name: "byWarehouse", fields: ["warehouseID", "id"]) {
id: ID!
name: String!
startDate: String!
phoneNumber: String!
warehouseID: ID!
jobTitle: String!
newHire: String! # You have to use String type, because Boolean types cannot be sort keys
}
type Warehouse @model {
id: ID!
employees: [Employee] @connection(keyName: "byWarehouse", fields: ["id"])
}
type AccountRepresentative
@model
@key(
name: "bySalesPeriodByOrderTotal"
fields: ["salesPeriod", "orderTotal"]
queryField: "repsByPeriodAndTotal"
) {
id: ID!
customers: [Customer] @connection(keyName: "byRepresentative", fields: ["id"])
orders: [Order] @connection(keyName: "byRepresentativebyDate", fields: ["id"])
orderTotal: Int
salesPeriod: String
}
type Inventory
@model
@key(
name: "byWarehouseID"
fields: ["warehouseID"]
queryField: "itemsByWarehouseID"
)
@key(fields: ["productID", "warehouseID"]) {
productID: ID!
warehouseID: ID!
inventoryAmount: Int!
}
type Product @model {
id: ID!
name: String!
orders: [Order] @connection(keyName: "byProduct", fields: ["id"])
inventories: [Inventory] @connection(fields: ["id"])
}

スキーマを作成したら、操作対象となるデータベース内のアイテムを作成しましょう:

# first
mutation createWarehouse {
createWarehouse(input: { id: "1" }) {
id
}
}
# second
mutation createEmployee {
createEmployee(
input: {
id: "amanda"
name: "Amanda"
startDate: "2018-05-22"
phoneNumber: "6015555555"
warehouseID: "1"
jobTitle: "Manager"
newHire: "true"
}
) {
id
jobTitle
name
newHire
phoneNumber
startDate
warehouseID
}
}
# third
mutation createAccountRepresentative {
createAccountRepresentative(
input: { id: "dabit", orderTotal: 400000, salesPeriod: "January 2019" }
) {
id
orderTotal
salesPeriod
}
}
# fourth
mutation createCustomer {
createCustomer(
input: {
id: "jennifer_thomas"
accountRepresentativeID: "dabit"
name: "Jennifer Thomas"
phoneNumber: "+16015555555"
}
) {
id
name
accountRepresentativeID
phoneNumber
}
}
# fifth
mutation createProduct {
createProduct(input: { id: "yeezyboost", name: "Yeezy Boost" }) {
id
name
}
}
# sixth
mutation createInventory {
createInventory(
input: { productID: "yeezyboost", warehouseID: "1", inventoryAmount: 300 }
) {
productID
inventoryAmount
warehouseID
}
}
# seventh
mutation createOrder {
createOrder(
input: {
amount: 300
date: "2018-07-12"
status: "pending"
accountRepresentativeID: "dabit"
customerID: "jennifer_thomas"
productID: "yeezyboost"
}
) {
id
customerID
accountRepresentativeID
amount
date
customerID
productID
}
}

1. 従業員 ID で従業員の詳細情報を検索

これは、従業員 ID を使用して従業員モデルをクエリするだけで実行できます。このを機能させるために @key または @connection は必要ありません。

query getEmployee($id: ID!) {
getEmployee(id: $id) {
id
name
phoneNumber
startDate
jobTitle
}
}

2. 従業員名で従業員の詳細情報をクエリ

Employee 型の @key byName は、内部的にインデックスが作成され、名前フィールドに対してマッチするクエリが使用されるため、このアクセスパターンを実現できます。次のクエリを使用できます:

query employeeByName($name: String!) {
employeeByName(name: $name) {
items {
id
name
phoneNumber
startDate
jobTitle
}
}
}

3. 従業員の電話番号を検索

前のクエリのいずれかを使用して従業員の電話番号を検索できます(従業員の ID または名前がある場合)。

4. 顧客の電話番号を検索

顧客モデルに対する前述と同様のクエリを実行すると、顧客の電話番号が得られます。

query getCustomer($customerID: ID!) {
getCustomer(id: $customerID) {
phoneNumber
}
}

5. 特定の顧客の指定期間内の注文を取得

顧客のすべての注文をクエリできるようにする 1 対多の関係があります。

この関係は、Order モデルに @keybyCustomerByDate を持たせ、Customer モデルの orders フィールドの接続によってクエリされることで作成されます。

日付付きのソートキーが使用されます。これが意味するところは、GraphQL リゾルバーが Between などの述語を使用して、データベースのすべてのレコードをスキャンしてからフィルタリングするのではなく、効率的に日付範囲を検索できるということです。

顧客への注文を日付範囲内で取得するために必要なクエリは次のようになります:

query getCustomerWithOrdersByDate($customerID: ID!) {
getCustomer(id: $customerID) {
ordersByDate(date: { between: ["2018-01-22", "2020-10-11"] }) {
items {
id
amount
productID
}
}
}
}

6. 指定期間内のすべての顧客の未処理注文を表示

@key byCustomerByStatusByDate により、このアクセスパターンで機能するクエリを実行できます。

この例では、statusdate を備えた複合ソートキー(2 つ以上のキーの組み合わせ)が使用されます。これが意味するところは、データベース内のレコードの一意の識別子がこれら 2 つのフィールド(status と date)を連結して作成され、GraphQL リゾルバーが Between または Contains などの述語を使用して、データベースのすべてのレコードをスキャンしてからフィルタリングするのではなく、一意の識別子を効率的に検索してマッチを見つけることができるということです。

query getCustomerWithOrdersByStatusDate($customerID: ID!) {
getCustomer(id: $customerID) {
ordersByStatusDate(
statusDate: {
between: [
{ status: "pending", date: "2018-01-22" }
{ status: "pending", date: "2020-10-11" }
]
}
) {
items {
id
amount
date
}
}
}
}

7. 最近採用されたすべての従業員を表示

Employee モデルに @key(name: "newHire", fields: ["newHire", "id"]) を持つことで、従業員が最近採用されたかどうかでクエリできます。

query employeesNewHire {
employeesNewHire(newHire: "true") {
items {
id
name
phoneNumber
startDate
jobTitle
}
}
}

employeesNewHireByStartDate クエリを使用して、開始日で結果が返されるようにクエリすることもできます:

query employeesNewHireByDate {
employeesNewHireByStartDate(newHire: "true") {
items {
id
name
phoneNumber
startDate
jobTitle
}
}
}

8. 特定の倉庫で働くすべての従業員を検索

これには、倉庫から従業員への 1 対多の関係が必要です。Warehouse モデルの @connection から見られるように、この接続は Employee モデルの byWarehouse キーを使用します。関連するクエリは次のようになります:

query getWarehouse($warehouseID: ID!) {
getWarehouse(id: $warehouseID) {
id
employees {
items {
id
name
startDate
phoneNumber
jobTitle
}
}
}
}

9. 特定の製品の注文中のすべてのアイテムを取得

このアクセスパターンは、製品から注文への 1 対多の関係を使用します。このクエリを使用して、特定の製品のすべての注文を取得できます:

query getProductOrders($productID: ID!) {
getProduct(id: $productID) {
id
orders {
items {
id
status
amount
date
}
}
}
}

10. すべての倉庫での特定の製品の現在の在庫を取得

すべての倉庫で製品の在庫を取得するために必要なクエリは次のようになります:

query getProductInventoryInfo($productID: ID!) {
getProduct(id: $productID) {
id
inventories {
items {
warehouseID
inventoryAmount
}
}
}
}

11. アカウント担当者による顧客を取得

これはアカウント担当者と顧客間の 1 対多の接続を使用します:

必要なクエリは次のようになります:

query getCustomersForAccountRepresentative($representativeId: ID!) {
getAccountRepresentative(id: $representativeId) {
customers {
items {
id
name
phoneNumber
}
}
}
}

12. アカウント担当者と日付による注文を取得

AccountRepresentative モデルから見られるように、この接続は Order モデルの byRepresentativebyDate フィールドを使用して必要な接続を作成します。必要なクエリは次のようになります:

query getOrdersForAccountRepresentative($representativeId: ID!) {
getAccountRepresentative(id: $representativeId) {
id
orders(date: { between: ["2010-01-22", "2020-10-11"] }) {
items {
id
status
amount
date
}
}
}
}

13. 特定の製品の注文中のすべてのアイテムを取得

これは番号 9 と同じです。

14. 特定の職種を持つすべての従業員を取得

byTitle @key を使用することで、このアクセスパターンは非常に簡単になります。

query employeesByJobTitle {
employeesByJobTitle(jobTitle: "Manager") {
items {
id
name
phoneNumber
jobTitle
}
}
}

15. 製品と倉庫による在庫を取得

ここでは、別のモデルに在庫を保持することが特に便利です。このモデルは独自のパーティションキーとソートキーを持つことができるため、このアクセスパターンで必要なように在庫自体をクエリできます。

このモデルのクエリは次のようになります:

query inventoryByProductAndWarehouse($productID: ID!, $warehouseID: ID!) {
getInventory(productID: $productID, warehouseID: $warehouseID) {
productID
warehouseID
inventoryAmount
}
}

byWarehouseID キーで作成された itemsByWarehouseID クエリを使用することで、個別の倉庫からすべての在庫を取得することもできます:

query byWarehouseId($warehouseID: ID!) {
itemsByWarehouseID(warehouseID: $warehouseID) {
items {
inventoryAmount
productID
}
}
}

16. 製品の総在庫を取得

これの方法はユースケースに依存します。すべての倉庫のすべての在庫のリストが必要な場合は、Inventory モデルで list inventories を実行するだけです:

query listInventorys {
listInventorys {
items {
productID
warehouseID
inventoryAmount
}
}
}

17. 注文合計と販売期間でランク付けされたアカウント担当者を取得

販売期間は日付範囲、またはおそらく月や週さえも考えられます。したがって、販売期間を文字列として設定し、salesPeriodorderTotal の組み合わせを使用してクエリできます。sortDirection を設定して、戻り値を最大から最小まで取得することもできます:

query repsByPeriodAndTotal {
repsByPeriodAndTotal(
sortDirection: DESC
salesPeriod: "January 2019"
orderTotal: { ge: 1000 }
) {
items {
id
orderTotal
}
}
}