Search code examples
pythonamazon-web-servicesamazon-dynamodbaws-sdkdynamodb-queries

【AWS DynamoDB】query nested items if sub key exist


Here is the item format on dynamodb table

{
 "id":"partition_key_id",
 "Products": {
    "ProductGroupA": [
      {
       "Description": "2",
      }
  ],
    "ProductGroupC": [
      {
       "Description": "3",
      }
  ]
 }
}

I attempted to query the item only if the nested key "Products.ProductGroupA" exists:


import boto3

dynamodb = boto3.client('dynamodb')

index_name = 'Products-index'

response = dynamodb.query(
    TableName='my_table',
    IndexName=index_name,
    FilterExpression='attribute_exists(#Products.#a)',
    ExpressionAttributeNames={
        '#Products': 'Products',
        '#a': 'ProductGroupA'
    },
)


However, I always received errors. Is it possible to achieve this goal using the 'query' method of boto3? I want to avoid 'scan' method because of consumption of RCU

If the query is not possible, are there any suggestions? Or should I adjust the structure format of dynamodb table. The reason I tried the nested format is easy to manage, but the reading efficiency makes it hard to implement so much.

Thank you so much. Have a good day !


Solution

  • When you created this index, you would have specified either a partition key or/and a sort key. These are then required fields to search by for your index to work. You are then in your query required to add a KeyConditionExpression before you can give it a FilterExpression

    response = dynamodb.query(
      IndexName='Products-Index',
      KeyConditionExpression='id = :id',
      FilterExpression='attribute_exists(Products.ProductGroupA)',
      ExpressionAttributeValues={
        ':id': 'partition_key_id',
      }
    )
    

    This method will then use your index to retrieve the objects that have partition_key_id and then will only scan through the results of that query.

    If this method does not suffice you will need to rethink your data model based off the access patterns you are working with.

    Hope this helps :) happy to try work with you to structure the format if you can provide more context around the data and how you want to retrieve it.