Paweł Łukasiewicz
2024-03-05
Paweł Łukasiewicz
2024-03-05
Udostępnij Udostępnij Kontakt
Wprowadzenie

Operacja Query w DynamoDB znajduje elementy na podstawie wartości klucza głównego.

Przy tej operacji musimy podać nazwę atrybutu klucza partycji i pojedynczą wartość dla tego atrybutu. Query zwraca wszystkie elementy z tą wartością klucza partycji. Opcjonalnie możemy również podać atrybut klucza sortowania i użyć operatora porównania, aby zawęzić wyniki wyszukiwania.

W tym wpisie poruszymy kilka tematów do których możemy zaliczyć wyrażenia filtrujące dla zapytania, paginację wyników, zliczanie elementów w wynikach, spójność odczytu danych czy zapytania dla tabeli i indeksów dla .NET. Zaczniemy jednak od kluczowych wyrażeń warunkowych dla zapytań.

Kluczowe wyrażenia warunkowe dla zapytania

W celu określenia kryteriów wyszukiwania musimy użyć wyrażenia wartości klucza (key condtion expression) – ciąg znaków, który określa elementy do odczytania z tabeli lub indeksu.

W pierwszym kroku musimy określić nazwę klucza partycji i wartość jako warunek równości. Nie możemy użyć atrybutu nie będącego kluczem w wyrażeniu warunku klucza.

Opcjonalnie możemy podać drugi warunek dla klucza sortowania (o ile został zdefiniowany). Warunek klucza sortowania musi używać jednego z następujących operatorów porównania:

  • a = b - prawda, jeżeli atrybut a jest równy wartości b;
  • a < b - prawda jeśli a jest mniejsze od b;
  • a <= b - prawda, jeśli a jest mniejsze lub równe wartości b;
  • a > b - prawda, jeśli a jest większe od b;
  • a >= b - prawda, jeśli a jest większe lub równe b;
  • a BETWEEN b AND c - prawda, jeśli a jest większe lub równe b oraz mniejsze lub równe c.
Możemy również wykorzystać poniższą funkcję:
  • begins_with (a, substr) - prawda, jeśli wartość atrybutu zaczyna się od określonego podciągu znaków.

Wyrażenia filtrujące dla zapytań

Jeżeli potrzebujemy bardziej zawęzić wyniki wyszukiwania możemy wykorzystać (opcjonalne) wyrażenia filtrujące. Wyrażenie to określa, które elementy w wynikach zapytania powinny zostać zwrócone do użytkownika – wszystkie inne zostaną odrzucone.

Wyrażenie filtrujące jest stosowane po zakończeniu zapytania, ale przed zwróceniem wyników. Dlatego też, niezależnie od obecności wyrażenia filtrującego, zapytanie zużywa taką samą ilość pamięci odczytu.

Operacja zapytania (Query) może pobrać maksymalnie 1MB danych. Limit ten obowiązuje przed obliczeniem zużycia wyrażenia filtrującego.

Wyrażenie filtrujące nie może zawierać atrybutów klucza partycji lub klucza sortowania. Atrybuty te należy zdefiniować w wyrażeniu warunku klucza a nie wyrażeniu filtra.

Składania wyrażenia filtra jest podoba do składni wyrażenia warunku klucza. Wyrażenia filtrujące mogą używać tych samych komparatorów, funkcji i operatorów logicznych co wyrażenia warunku klucza. Ponadto, wyrażenia filtrujące mogą używać operatora not-equals (<>), operatora OR, CONTAINS, IN, BEGINS_WITH, BETWEEN, EXISTS oraz operatora SIZE.

Ograniczenie liczby elementów w zbiorze wyników

Operacja Query pozwala na ograniczenie liczby odczytywanych przez nią elementów. W tym celu należy posłużyć się parametrem Limit, który określa maksymalną liczbę elementów do zwrócenia.

Załóżmy, że wykonujemy Query (zapytanie) do tabeli z wartością Limit ustawioną na 8 i bez wyrażenia filtrującego. W wynikach zapytania dostaniemy 8 pierwszych elementów z tabeli, które odpowiadają kluczowemu wyrażeniu warunkowemu z zapytania.

Kolejny przykład niech obejmuje również wyrażenie filtrujące. W tym przypadku DynamoDB odczytuje do 8 elementów a następnie zwraca tylko te, które pasują do wyrażenia filtrującego. Końcowy wynik zapytania zawiera 8 lub mniej elementów nawet jeżeli pasowałby do wyrażenia filtrującego, gdyby DynamoDB odczytał więcej elementów.

Liczenie elementów w wynikach

Oprócz elementów spełniających kryteria, odpowiedź Query zawiera również następujące elementy:

  • ScannedCount - liczba elementów, które pasowały do kluczowego wyrażenia warunkowego przed zastosowaniem wyrażenia filtrującego (jeśli te zostały określone);
  • Count - liczba elementów, które pozostały po zastosowaniu wyrażenia filtrującego (jeśli zostały określone).

Warto pamiętać, że jeżeli nie zostanie zastosowane wyrażenie filtrujące to wartości atrybutów ScannedCount i Count mają tę samą wartość.

Jeżeli rozmiar zbioru wyników Query jest większy niż 1MB, ScannedCount i Count reprezentują tylko częściowe zliczenie wszystkich elementów. Musimy wykonać wiele operacji Query, aby pobrać wszystkie wyniki (o paginacji porozmawiamy za chwilę).

Każda odpowiedź zawiera ScannedCount oraz Count dla elementów, które zostały przetworzone przez dane zapytanie. W celu uzyskania sum całkowitych dla wszystkich zapytań Query można zachować bieżące wartości zarówno dla ScannedCount jak i Count.

Jednostki pojemności zużyte przez zapytanie

Możesz wykonać zapytanie do dowolnej tabeli lub indeksu wtórnego pod warunkiem, że podasz nazwę atrybutu klucza partycji i pojedynczą wartość tego atrybutu. Zapytanie zwróci wszystkie elementy z tą wartością klucza partycji. Opcjonalnie możemy podać atrybut klucza sortowania i użyć operatora porówniania, aby zawęzić wyniki wyszukiwania. Operacje zapytań zużywają jednostki pojemności odczytu tak jak przedstawiono to w poniższej tabeli:

Jeżeli zapytasz... DynamoDB zużywa jednostki pojemności do odczytu z...
Tabelę Pojemność odczytu tabeli
Globalny indeks wtórny Pojemność odczytu indeksu
Lokalny indeks wtórny Pojemność odczytu tabeli podstawowej

Domyślnie, Query, nie zwraca żadnych danych na temat ilości zużytej pojemności odczytu. Możemy jednak określić parametr ReturnConsumedCapacity w żądaniu zapytania, aby uzyskać te informacje. Poniżej przykład poprawnych ustawień wspomnianego wcześniej parametru:

  • NONE - nie są zwracane żadne informacje o zużytej pojemności (ustawienie domyślne);
  • TOTAL - odpowiedź zawiera łączną liczbę zużytych jednostek pojemności odczytu;
  • INDEXES - odpowiedź zawiera zbiorczą liczbę jednostek pojemności odczytu wraz z pojemnością zużytą dla każdej tabeli i indeksu do których uzyskano dostęp.

DynamoDB oblicza liczbę zużytych jednostek pojemności odczytu na podstawie rozmiaru elementu a nie ilości danych zwracanych do aplikacji. Z tego powodu liczba zużytych jednostek pojemności jest taka sama, niezależnie od tego, czy żądasz wszystkich atrybutów (zachowanie domyślne) czy tylko niektórych z nich (używając wyrażenia projekcji). Liczba ta jest również taka sama niezależnie od tego czy używasz wyrażenia filtrującego czy nie. Zapytanie zużywa minimalną jednostkę pojemności odczytu (0.5 przy domyślnej spójności oraz 1.0 przy odczycie silnie spójnym) dla każdej partycji biorącej udział w obsłudze zapytania – dotyczy to również partycji nie zawierających żadnych elementów.

Spójność odczytu w zapytaniach

Operacja zapytania wykonuje domyślnie spójny odczyt, tj. consistent read - oznacza to, że wyniki zapytania mogą nie odzwierciedlać zmian spowodowanych ostatnio wykonanymi operacjami PutItem lub UpdateItem.

Więcej na ten temat możecie przeczytać w oficjalnej dokumentacji: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadConsistency.html

Jeżeli wymagany jest silnie spójny odczyt (strongly consistent read) należy ustawić parametr ConsistentRead na true w wykonywanym zapytaniu. Ustawienie silnie spójnego odczytu zwróci nam wyniki z najbardziej aktualnymi danymi uwzględniającymi aktualizację wszystkich wcześniejszych operacji, które zakończyły się sukcesem. Odczyt ten ma jednak wady o których pisałem tutaj: DynamoDB - podstawowe pojęcia

To tyle w ramach teorii, w kolejnym wpisie wykorzystamy API AWS SDK dla .NET i przejdziemy przez praktyczne przykłady.