Paweł Łukasiewicz
2024-02-20
Paweł Łukasiewicz
2024-02-20
Udostępnij Udostępnij Kontakt
Wprowadzenie

Metoda BatchGetItem pozwala na pobranie wielu elementów z jednej lub wielu tabel. Jak doskonale pamiętacie, pobranie pojedynczego elementu jest możliwe dzięki metodzie GetItem.

W celu wykorzystania metody BatchGetItem musimy przygotować żądanie wykorzystując instancję klasy BatchGetItemRequest podając nazwę tabeli i listę wartości klucza głównego. Kolejny krok to wywołanie metody BatchGetItem wykorzystując powyższy obiekt żądania jako parametr. Podobnie, jak w przypadku poprzedniego wpisu, powinniśmy sprawdzić czy w odpowiedzi nie było żadnych nieprzetworzonych kluczy do czego mogło dojść w przypadku osiągnięcia przewidzianego limitu przepustowości lub innego przejściowego błędu związanego z dostępem do danych.

W poniższym przykładzie pobierzemy elementy z dwóch tabel, tj. CarCatalog oraz Orders. Pobierzemy oba elementy z pierwszej tabeli oraz jeden z drugiej:

public async Task<ActionResult<string>> GetItemBatch()
{
    var request = new BatchGetItemRequest
    {
        RequestItems = new Dictionary<string, KeysAndAttributes>
        {
            { TableName1, new KeysAndAttributes
            {
                Keys = new List<Dictionary<string, AttributeValue>>()
                {
                    new Dictionary<string, AttributeValue>
                    {
                        { "Id", new AttributeValue { N = "1" } }
                    },
                    new Dictionary<string, AttributeValue>
                    {
                        { "Id", new AttributeValue { N = "2" } }
                    }
                }
            } },
            {
                TableName2, new KeysAndAttributes
                {
                    Keys = new List<Dictionary<string, AttributeValue>>()
                    {
                        new Dictionary<string, AttributeValue>
                        {
                            { "Id", new AttributeValue {N = "1"} },
                        }
                    }
                }
            }
        }
    };

    var response = await _amazonDynamoDB.BatchGetItemAsync(request);
    // Sprawdzenie odpowiedzi
    // Lista atrybytów
    var result = response.Responses;

    StringBuilder sb = new StringBuilder();

    // Poniższy kod moglibyśmy napisać w bardziej przejrzysty sposób
    // to jednak nie temat tego wpisu
    var table1Results = result[TableName1];
    sb.AppendLine($"Items in table {TableName1}");
    foreach (var carDictionary in table1Results)
    {
        // Zerknicie tutaj: https://www.plukasiewicz.net/AwsLambda/DynamoDbLambda
        // jeżeli checie pobrać wartości danych atrybutów w dokładniejszy sposób
        string json = JsonConvert.SerializeObject(carDictionary, Formatting.Indented);
        sb.AppendLine(json);
    }

    var table2Results = result[TableName2];
    sb.AppendLine($"Items in table {TableName2}");
    foreach (var orderDictionary in table2Results)
    {
        string json = JsonConvert.SerializeObject(orderDictionary, Formatting.Indented);
        sb.AppendLine(json);
    }

    // Sprawdzmy czy mamy jakies nieprzetworzone klucze
    // Powód: przekroczenie ProvisionedThroughput lub inny problem
    Dictionary<string, KeysAndAttributes> unprocessedKeys = response.UnprocessedKeys;
    foreach (KeyValuePair<string, KeysAndAttributes> pair in unprocessedKeys)
    {
        sb.AppendLine("Nieprzetworzone klucze: ");
        sb.AppendLine($"{pair.Key}, {pair.Value}");
    }

    return sb.ToString();
}
Jeżeli zależy Wam na dokładniejszym sprawdzeniu/wyciągnięciu odpowiedzi zachęcam do zerknięcia do tego wpisu: AWS Lambda - Lambda z DynamoDB w którym pokazałem dynamiczne mapowanie używane w DynamoDB.

Parametry opcjonalne

Obiekt BatchGetItemRequest pozwala również na przekazanie parametrów opcjonalnych. W poniższym przykładzie wykorzystamy parametr ProjectionExression, która określa atrybuty elementu do zwrócenia:

public async Task<ActionResult<string>> GetItemBatchWithParameters()
{
    var request = new BatchGetItemRequest
    {
        RequestItems = new Dictionary<string, KeysAndAttributes>
        {
            { TableName1, new KeysAndAttributes
            {
                Keys = new List<Dictionary<string, AttributeValue>>()
                {
                    new Dictionary<string, AttributeValue>
                    {
                        { "Id", new AttributeValue { N = "1" } }
                    },
                    new Dictionary<string, AttributeValue>
                    {
                        { "Id", new AttributeValue { N = "2" } }
                    }
                },
                ProjectionExpression = "Brand, Model"
            } },

        }
    };

    var response = await _amazonDynamoDB.BatchGetItemAsync(request);
    // Sprawdzenie odpowiedzi
    // Lista atrybytów
    var result = response.Responses;

    StringBuilder sb = new StringBuilder();

    // Poniższy kod moglibyśmy napisać w bardziej przejrzysty sposób
    // to jednak nie temat tego wpisu
    var table1Results = result[TableName1];
    sb.AppendLine($"Items in table {TableName1}");
    foreach (var carDictionary in table1Results)
    {
        // Zerknicie tutaj: https://www.plukasiewicz.net/AwsLambda/DynamoDbLambda
        // jeżeli checie pobrać wartości danych atrybutów w dokładniejszy sposób
        string json = JsonConvert.SerializeObject(carDictionary, Formatting.Indented);
        sb.AppendLine(json);
    }

    return sb.ToString();
}