ในโมดูลนี้ คุณจะได้เรียนรู้ตัวอย่างง่ายๆ ในการเรียกรายการแบบหลายรายการในการเรียกใช้ API เดียวด้วย DynamoDB นอกจากนี้ คุณยังจะได้เรียนรู้วิธีการใช้ดัชนีรองเพื่อเปิดใช้งานรูปแบบการสืบค้นเพิ่มเติมในตาราง DynamoDB ของคุณ

ระยะเวลาที่ใช้ในการศึกษาโมดูล: 15 นาที


ในโมดูล 2 คุณได้ทราบวิธีการเรียกหนังสือเล่มเดียวจากตาราง DynamoDB โดยใช้การเรียกใช้ API GetItem แล้ว รูปแบบการเข้าถึงนี้มีประโยชน์ แต่แอปพลิเคชันของคุณยังต้องมีความสามารถในการเรียกรายการหลายรายการในการเรียกใช้ครั้งเดียวได้ด้วย ตัวอย่างเช่น คุณอาจต้องการเรียกหนังสือทุกเล่มที่แต่งโดย John Grisham เพื่อให้คุณสามารถรายการให้กับผู้ใช้ได้ ในขั้นตอนที่ 1 ในโมดูลนี้ คุณจะต้องใช้ API การสืบค้น เพื่อเรียกหนังสือทุกเล่มตามผู้แต่งเฉพาะ

การเรียกใช้ API GetItem เพื่อหาหนังสือเล่มเดียวและการเรียกใช้ API การสืบค้น เพื่อเรียกหนังสือทุกเล่มตามผู้แต่ง จะใช้คีย์หลักที่ระบุในตาราง หนังสือ ของคุณ อย่างไรก็ตาม คุณอาจต้องการเปิดใช้งานรูปแบบการเข้าถึงเพิ่มเติม เช่น การเรียกหนังสือทุกเล่มเฉพาะหมวดหมู่ เช่น หมวดประวัติศาสตร์หรือชีวประวัติ หมวดหมู่ ไม่ได้อยู่ในคีย์หลักของตารางของคุณ แต่คุณสามารถสร้างดัชนีรองเพื่ออนุญาตให้ใช้รูปแบบการเข้าถึงเพิ่มเติมได้ คุณจะต้องสร้างดัชนีรองและสืบค้นดัชนีรองในขั้นตอนที่ 2 และ 3 ในโมดูลนี้


  • ขั้นตอนที่ 1 เรียกรายการหลายรายการที่มีการสืบค้น

    เมื่อตารางของคุณใช้คีย์หลักแบบรวม คุณจะสามารถเรียกรายการทั้งหมดที่มีแฮชคีย์เดียวกัน โดยใช้การเรียกใช้ API การสืบค้น สำหรับแอปพลิเคชันของคุณ ข้อนี้หมายความว่าคุณสามารถเรียกหนังสือทุกเล่มที่มีคุณลักษณะ ผู้แต่ง เดียวกันได้

    ในเทอร์มินัล AWS Cloud9 ให้เรียกใช้คำสั่งต่อไปนี้

    $ python query_items.py

    คำสั่งนี้จะเรียกใช้สคริปต์ต่อไปนี้ ซึ่งจะเรียกหนังสือทุกเล่มที่แต่งโดย John Grisham

    import boto3
    from boto3.dynamodb.conditions import Key
    
    # boto3 is the AWS SDK library for Python.
    # The "resources" interface allows for a higher-level abstraction than the low-level client interface.
    # For more details, go to http://boto3.readthedocs.io/en/latest/guide/resources.html
    dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
    table = dynamodb.Table('Books')
    
    # When making a Query API call, you use the KeyConditionExpression parameter to specify the hash key on which you want to query.
    # You’re using the Key object from the Boto 3 library to specify that you want the attribute name ("Author")
    # to equal "John Grisham" by using the ".eq()" method.
    resp = table.query(KeyConditionExpression=Key('Author').eq('John Grisham'))
    
    print("The query returned the following items:")
    for item in resp['Items']:
        print(item)

    หลังจากที่คุณเรียกใช้สคริปต์แล้ว คุณจะเห็นหนังสือของ John Grisham สองเล่มที่มีชื่อว่า The Firm และ The Rainmaker

    $ python query_items.py
    The query returned the following items:
    {'Title': 'The Firm', 'Formats': {'Hardcover': 'Q7QWE3U2', 'Paperback': 'ZVZAYY4F', 'Audiobook': 'DJ9KS9NM'}, 'Author': 'John Grisham', 'Category': 'Suspense'}
    {'Title': 'The Rainmaker', 'Formats': {'Hardcover': 'J4SUKVGU', 'Paperback': 'D7YF4FCX'}, 'Author': 'John Grisham', 'Category': 'Suspense'}

    การเรียกรายการหลายรายการด้วยการเรียกใช้ครั้งเดียวใน DynamoDB นั้นเป็นรูปแบบที่พบโดยทั่วไปและทำได้ง่ายด้วยการเรียกใช้ API การสืบค้น

  • ขั้นตอนที่ 2 การสร้างดัชนีรอง

    DynamoDB ช่วยให้คุณสามารถสร้างดัชนีรองในบัญชีสำหรับรูปแบบการเข้าถึงข้อมูลเพิ่มเติมในตารางของคุณได้ ดัชนีรองเป็นวิธีการเพิ่มความยืดหยุ่นในการสืบค้นที่มีประสิทธิภาพสูงลงในตาราง DynamoDB

    DynamoDB มีดัชนีรอง 2 ประเภท ได้แก่ ดัชนีรองโดยรวมและดัชนีรองภายในเครื่อง ในส่วนนี้ คุณจะต้องเพิ่มดัชนีรองลงในคุณลักษณะหมวดหมู่ของคุณ ซึ่งจะช่วยให้คุณสามารถเรียกหนังสือทุกเล่มเฉพาะหมวดหมู่ได้

    ตัวอย่างสคริปต์ต่อไปนี้จะเพิ่มดัชนีรองโดยรวมลงในตารางที่มีอยู่

    import boto3
    
    # Boto3 is the AWS SDK library for Python.
    # You can use the low-level client to make API calls to DynamoDB.
    client = boto3.client('dynamodb', region_name='us-east-1')
    
    try:
        resp = client.update_table(
            TableName="Books",
            # Any attributes used in your new global secondary index must be declared in AttributeDefinitions
            AttributeDefinitions=[
                {
                    "AttributeName": "Category",
                    "AttributeType": "S"
                },
            ],
            # This is where you add, update, or delete any global secondary indexes on your table.
            GlobalSecondaryIndexUpdates=[
                {
                    "Create": {
                        # You need to name your index and specifically refer to it when using it for queries.
                        "IndexName": "CategoryIndex",
                        # Like the table itself, you need to specify the key schema for an index.
                        # For a global secondary index, you can use a simple or composite key schema.
                        "KeySchema": [
                            {
                                "AttributeName": "Category",
                                "KeyType": "HASH"
                            }
                        ],
                        # You can choose to copy only specific attributes from the original item into the index.
                        # You might want to copy only a few attributes to save space.
                        "Projection": {
                            "ProjectionType": "ALL"
                        },
                        # Global secondary indexes have read and write capacity separate from the underlying table.
                        "ProvisionedThroughput": {
                            "ReadCapacityUnits": 1,
                            "WriteCapacityUnits": 1,
                        }
                    }
                }
            ],
        )
        print("Secondary index added!")
    except Exception as e:
        print("Error updating table:")
        print(e)

    การสร้างดัชนีรองโดยรวมกับการสร้างตารางมีวิธีการที่เหมือนกันมาก คุณจะต้องระบุชื่อสำหรับดัชนี คุณลักษณะที่จะอยู่ในดัชนี สคีมาคีย์ของดัชนี และปริมาณการประมวลผลเตรียมไว้ (ความจุสูงสุดที่แอปพลิเคชันสามารถใช้งานจากตารางหรือดัชนี) ปริมาณการประมวลผลที่เตรียมไว้ในแต่ละดัชนีจะแยกออกจากปริมาณการประมวลผลที่เตรียมไว้ในตาราง ส่วนนี้จะช่วยให้คุณสามารถกำหนดปริมาณการประมวลผลโดยละเอียดเพื่อให้สอดคล้องกับความต้องการของแอปพลิเคชัน

    เรียกใช้คำสั่งต่อไปนี้ในเทอร์มินัลเพื่อเพิ่มดัชนีรองโดยรวมของคุณ

    $ python add_secondary_index.py

    สคริปต์นี้จะเพิ่มดัชนีรองโดยรวมที่มีชื่อว่า CategoryIndex ลงในตาราง หนังสือ ของคุณ

  • ขั้นตอนที่ 3 การสืบค้นดัชนีรอง

    ตอนนี้คุณมี CategoryIndex แล้ว คุณสามารถใช้เพื่อเรียกหนังสือทุกเล่มเฉพาะหมวดหมู่ได้ การใช้ดัชนีรองเพื่อสืบค้นตารางคล้ายคลึงกับการใช้การเรียกใช้ API การสืบค้น ตอนนี้ คุณจะต้องเพิ่มชื่อดัชนีลงในการเรียกใช้ API

    เมื่อคุณเพิ่มดัชนีรองโดยรวมลงในตารางที่มีอยู่ DynamoDB จะเติมดัชนีแบบอะซิงโครนัสด้วยรายการที่มีอยู่ในตาราง ดัชนีจะพร้อมสำหรับการสืบค้นหลังจากที่เติมรายการทั้งหมดแล้ว เวลาที่ใช้ในการเติมข้อมูลนั้นจะแตกต่างกันไปตามขนาดของตาราง

    คุณสามารถใช้สคริปต์ query_with_index.py เพื่อสืบค้นกับดัชนีใหม่ได้ เรียกใช้สคริปต์ในเทอร์มินัลด้วยคำสั่งต่อไปนี้

    $ python query_with_index.py

    คำสั่งดังกล่าวจะเรียกใช้สคริปต์ต่อไปนี้ในการเรียกหนังสือทุกเล่มในร้านที่มี หมวดหมู่ สืบสวนสอบสวน

    import time
    
    import boto3
    from boto3.dynamodb.conditions import Key
    
    # Boto3 is the AWS SDK library for Python.
    # The "resources" interface allows for a higher-level abstraction than the low-level client interface.
    # For more details, go to http://boto3.readthedocs.io/en/latest/guide/resources.html
    dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
    table = dynamodb.Table('Books')
    
    # When adding a global secondary index to an existing table, you cannot query the index until it has been backfilled.
    # This portion of the script waits until the index is in the “ACTIVE” status, indicating it is ready to be queried.
    while True:
        if not table.global_secondary_indexes or table.global_secondary_indexes[0]['IndexStatus'] != 'ACTIVE':
            print('Waiting for index to backfill...')
            time.sleep(5)
            table.reload()
        else:
            break
    
    # When making a Query call, you use the KeyConditionExpression parameter to specify the hash key on which you want to query.
    # If you want to use a specific index, you also need to pass the IndexName in our API call.
    resp = table.query(
        # Add the name of the index you want to use in your query.
        IndexName="CategoryIndex",
        KeyConditionExpression=Key('Category').eq('Suspense'),
    )
    
    print("The query returned the following items:")
    for item in resp['Items']:
        print(item)

    โปรดทราบว่า มีสคริปต์ส่วนหนึ่งที่จะรอจนกว่าดัชนีจะพร้อมทำการสืบค้น

    คุณจะเห็นผลลัพธ์ต่อไปนี้ในเทอร์มินัลของคุณ:

    $ python query_with_index.py
    The query returned the following items:
    {'Title': 'The Firm', 'Formats': {'Hardcover': 'Q7QWE3U2', 'Paperback': 'ZVZAYY4F', 'Audiobook': 'DJ9KS9NM'}, 'Author': 'John Grisham', 'Category': 'Suspense'}
    {'Title': 'The Rainmaker', 'Formats': {'Hardcover': 'J4SUKVGU', 'Paperback': 'D7YF4FCX'}, 'Author': 'John Grisham', 'Category': 'Suspense'}
    {'Title': 'Along Came a Spider', 'Formats': {'Hardcover': 'C9NR6RJ7', 'Paperback': '37JVGDZG', 'Audiobook': '6348WX3U'}, 'Author': 'James Patterson', 'Category': 'Suspense'}

    การสืบค้นจะส่งคืนหนังสือ 3 เล่มตามผู้แต่ง 2 คน ส่วนนี้คือรูปแบบการสืบค้นที่อาจจะยากสำหรับสคีมาคีย์หลักของตารางของคุณ แต่ง่ายต่อการนำไปใช้กับความสามารถของดัชนีรอง


    ในโมดูลถัดไป คุณจะได้เรียนรู้วิธีการอัปเดตคุณลักษณะของรายการที่มีอยู่ในตาราง โดยใช้ API UpdateItem