DynamoDB query with FilterExpression returns no results even when records exist

0

I'm querying a DynamoDB GSI (parentUploadId-index) to get the first incomplete record (where status <> "COMPLETED") for a given parentUploadId. Here's my code:

public async Task<(int, int)> QueryFirstIncompleteRecordAsync(int parentUploadId)
{
    Dictionary<string, AttributeValue> lastEvaluatedKey = null;
    do
    {
        var queryRequest = new QueryRequest
        {
            TableName = _tableName,
            IndexName = "parentUploadId-index",
            KeyConditionExpression = "parentUploadId = :parentId",
            FilterExpression = "#status <> :completedStatus",
            ExpressionAttributeNames = new() { { "#status", "status" } },
            ExpressionAttributeValues = new()
            {
                { ":parentId", new AttributeValue { S = parentUploadId.ToString() } },
                { ":completedStatus", new AttributeValue { S = "COMPLETED" } }
            },
            ExclusiveStartKey = lastEvaluatedKey
        };

        var response = await _db.QueryAsync(queryRequest);

        var record = response.Items
            .Select(i => new
            {
                UploadId = int.Parse(i["uploadId"].S),
                ParentUploadId = int.Parse(i["parentUploadId"].S)
            })
            .OrderBy(r => r.UploadId)
            .FirstOrDefault();

        if (record != null)
            return (record.UploadId, record.ParentUploadId);

        lastEvaluatedKey = response.LastEvaluatedKey;
    } while (lastEvaluatedKey != null);

    return (0, parentUploadId);
}

Problem: Even when valid records exist (e.g., status = "PENDING"), the method returns (0, parentUploadId).

Is there a better way to handle this filtering or a known issue with <> in FilterExpression?

Note: I'm calling this query milliseconds after inserting the records. Could it be a GSI propagation delay issue?

asked 16 days ago40 views
1 Answer
2

The issue you're experiencing could indeed be related to the Global Secondary Index (GSI) propagation delay. When you insert new items or update existing ones in DynamoDB, there can be a slight delay before these changes are reflected in the GSI. This delay is typically very short (usually within milliseconds), but it can occasionally be longer.

Given that you're calling the query immediately after inserting the records, it's possible that the GSI hasn't been fully updated yet. This could explain why you're not seeing the expected results, even though the records exist in the base table.

To address this, you could try the following approaches:

  1. Add a small delay (e.g., 1-2 seconds) between inserting the records and querying the GSI. This might allow enough time for the index to be updated.

  2. Implement a retry mechanism with exponential backoff. If the query returns no results, wait for a short period and try again, increasing the wait time between attempts.

  3. If immediate consistency is crucial for your application, consider using the base table for querying instead of the GSI. While this might require a different query structure, it would provide strongly consistent reads.

  4. If possible, structure your data and queries to use the base table's primary key instead of a GSI. This would eliminate the propagation delay issue entirely.

Regarding the use of the "<>" operator in the FilterExpression, it is a valid operator and should work as expected. The issue is more likely related to the timing of the query rather than the syntax of the FilterExpression.

It's worth noting that filter expressions in DynamoDB are applied after the query has been executed. This means that even if no items match your filter, DynamoDB will still consume the same amount of read capacity. If you find that this query pattern is common in your application, you might want to consider restructuring your data model to allow for more efficient querying without relying heavily on filter expressions.

Lastly, ensure that your IAM permissions are correctly set to allow both querying the table and accessing the GSI. While this is unlikely to be the cause if you're able to query without the filter expression, it's always a good practice to double-check permissions when troubleshooting DynamoDB issues.
Sources
Filter expressions for the Query operation in DynamoDB - Amazon DynamoDB
Guidance for Real-Time Text Search Using Amazon OpenSearch Service

profile picture
answered 16 days ago
profile pictureAWS
EXPERT
reviewed 15 days ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions