Filter Expression not working in DynamoDb Table

0

I have a DynamoDb Table named "MenuItem" which has GSI named "CategoryId-CreatedDate-index" CategoryId is the Partition Key and CreatedDate is the Sort key. I am doing the following query operation in the AWS Console and getting 28 records as shown in the below screenshot.

Filter Error

But when I am doing the same thing via C# code then I am getting zero row count.

var menuRequest = new QueryRequest
            {
                TableName = MenutableName,
                IndexName = "CategoryId-CreatedDate-index",
                Limit = 10,
                ScanIndexForward = false,
                 KeyConditionExpression = "CategoryId = :v_Id",
                FilterExpression = "IsPublished = :ispub",
                ExpressionAttributeValues = new Dictionary<string, AttributeValue>
                {
                    {":v_Id", new AttributeValue { N =  "1" }},
                    {":ispub", new AttributeValue { BOOL = true }},
                }
            };

var menuResponse = await client.QueryAsync(menuRequest).ConfigureAwait(false);

Filter_Expression_c#_code_error

2개 답변
3
수락된 답변

Issue Explained

You API is not returning item due to the use of Limit = 10 parameter.

A single Query operation will read up to the maximum number of items set (if using the Limit parameter) or a maximum of 1 MB of data and then apply any filtering to the results using FilterExpression.

reference

So in your case, you read 10 items, apply the filter IsPublished=true, of which there are no matches, so you get returned an empty response.

ScannedCount

The number of items evaluated, before any QueryFilter is applied. A high ScannedCount value with few, or no, Count results indicates an inefficient Query operation

Count

The number of items in the response. If you used a QueryFilter in the request, then Count is the number of items returned after the filter was applied, and ScannedCount is the number of matching items before the filter was applied. If you did not use a filter in the request, then Count and ScannedCount are the same.

Resolution

To overcome this issue you can:

  1. Increase the limit, also consider using pagination incase your item collection exceed 1MB.
  2. Re-design your data model to include the IsPublished attribute as part of your sort key:
GSIPKGSISKIsPublished
CategoryId123false#2023-09-11T20:00:000zfalse
CategoryId123false#2023-09-11T21:00:000zfalse
CategoryId123true#2023-09-11T17:00:000ztrue
CategoryId123true#2023-09-11T10:00:000ztrue

This approach you can use Limit=10 and get exactly 10 items:

var menuRequest = new QueryRequest
            {
                TableName = MenutableName,
                IndexName = "CategoryId-CreatedDate-index",
                Limit = 10,
                ScanIndexForward = false,
                 KeyConditionExpression = "CategoryId = :v_Id AND begins_with(GSISK, :tt)",
                ExpressionAttributeValues = new Dictionary<string, AttributeValue>
                {
                    {":v_Id", new AttributeValue { N =  "1" }},
                    {":tt", new AttributeValue { S = "true" }},
                }
            };
profile pictureAWS
전문가
답변함 8달 전
profile picture
전문가
검토됨 7일 전
profile pictureAWS
전문가
검토됨 8달 전
0

Hi Atif,

The important thing to consider when using a Query Filter is the order that DynamoDB processes actions:

  1. Read items from your table
  2. If a filter expression is present, remove items that don't match the filter
  3. Return items

Your Query includes a Limit for the Query, so I suspect what's happening is that DynamoDB is reading 10 records as indicated by your "Limit=10", applying the filter to these 10 records, finds that none of them match your filter so returns (correctly) 0 items to you. In your output image you can see that "Scanned Count" is 10 showing that 10 records have been processed, but none have been returned.

I suggest having a read of the blog "When to use (and when not to use) DynamoDB Filter Expressions" as it explains what's going on and gives alternatives for how to query your data. With the information you've provided I suggest experimenting with using a new Global Secondary Index with CategoryId as the PK and IsPublished as the Sort Key. This should be a more efficient query for the use case you've described in your question, and will mean you can do a Query without using a Filter expression.

AWS
답변함 8달 전

로그인하지 않았습니다. 로그인해야 답변을 게시할 수 있습니다.

좋은 답변은 질문에 명확하게 답하고 건설적인 피드백을 제공하며 질문자의 전문적인 성장을 장려합니다.

질문 답변하기에 대한 가이드라인

관련 콘텐츠