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.
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.