amazon-web-servicesgoamazon-dynamodb

DynamoDB filter on a nested field value using Golang


Table name: MyTable Attribute name: data Keyword to filter: rally

Given an example value, how do I filter items where the attributes.label array contains a rally?

{
    "type": {
        "S": "play"
    },
    "attributes": {
        "M": {
            "term": {
                "S": "end_term"
            },
            "label": {
                "L": [
                    {
                        "S": "all_players"
                    },
                    {
                        "S": "rally"
                    },
                    {
                        "S": "race"
                    }
                ]
            },
            "currency": {
                "S": "USD"
            }
        }
    },
    "id": {
        "S": "a752d2"
    }
}

I used example below but it always returns 0 items.

    input := &dynamodb.ScanInput{
        TableName:        aws.String("MyTable"),
        FilterExpression: aws.String("contains(#path, :keyword)"),
        ExpressionAttributeNames: map[string]string{
            "#path": "attributes.label",
        },
        ExpressionAttributeValues: map[string]types.AttributeValue{
            ":keyword": &types.AttributeValueMemberS{Value: "rally"},
        },
    }

    result, err := c.client.Scan(context.TODO(), input)
    if err != nil {
        log.Fatalf("failed to scan items: %v", err)
    }

    fmt.Println(">>>>> Result", len(result.Items))

    for i, item := range result.Items {
        var data map[string]interface{}
        err := json.Unmarshal([]byte(item["data"].(*types.AttributeValueMemberS).Value), &data)
        if err != nil {
            log.Printf("failed to unmarshal item: %v", item)
            continue
        }
        fmt.Printf(">>>>> Item (%d): %+v", i, data)
    }

Solution

  • Path is a reserved word in Dynamodb. Can you try by using a different alias which is not part of this list of keywords reserved by Dynamodb.