2012-05-19 12 views
19

Jakieś pomysły, jak wybrać przedmiot/rekord losowo ze stołu DynamoDB? Nie sądzę, aby istniały jakiekolwiek przepisy na ten temat w API.AWS DynamoDB - Wybierz losowo rekord/przedmiot?

Pomyślałem o utrzymywaniu tabeli NumericId | MyOtherKey ("NumericIdTable"), a następnie generowaniu liczby losowej między 0 a całkowitą liczbą posiadanych rekordów, a następnie pobranie tego elementu z NumericIdTable, ale to nie zadziała w długi bieg.

Powitanie pomysłów/pomysłów.

Odpowiedz

20

Jedno podejście wymyśliłem aby wybrać losowy element z DynamoDB tabeli:

  1. wygenerować losowy RangeKey nad wszystkimi możliwymi RangeKeys w tabeli
  2. kwerendy tabeli z tym RangeKey i RangeKeyCondition GreaterThan i wysokości 1

na przykład, jeśli używasz UUID jako identyfikator dla RangeKey można uzyskać losowy przedmiot podobny do poniższego

RandomRangeKey = new UUID 
RandomItem = Query("HashKeyValue": "KeyOfRandomItems", 
        "RangeKeyCondition": { "AttributeValueList": 
           "RandomRangeKey", 
           "ComparisonOperator":"GT"}, 
        "Limit": 1) 

W ten sposób otrzymasz losowy przedmiot i zużyjesz tylko 1 pojemność odczytu.

Istnieje szansa na pominięcie pierwszego zapytania dla zmiennej losowej poprzez wygenerowanie mniejszego identyfikatora UUID niż najmniejszego używanego w tabeli. Ta szansa zmniejsza się wraz ze wzrostem stołu i możesz łatwo wysłać kolejną prośbę, używając porównania SmallerThan na tym samym losowym klawiszu, który zapewnia trafienie losowemu przedmiotowi.


Jeśli Tabledesign nie pozwala randomizable RangeKeys można śledzić swoje podejście i utworzyć oddzielną tabelę RandomItem i przechowywać identyfikator pod randomizable RangeKey. Możliwym Struktura tabeli dla tego byłoby

*RandomItemTable 
    TableName - HashKey 
    UUID - Rangekey 
    ItemId 

Pamiętaj, że dla tego podejścia trzeba zarządzać redundancję między oryginalnej tabeli i tabeli randomizacji.

+2

Dzięki za to NENTi - przyjrzę się realizacji tego. Muszę przyznać, że nie myślałem o używaniu operatora porównywania GT na UUID - fajny pomysł :) – ben

+2

Zapytanie DynamoDB musi określić klucz skrótu. powyższa odpowiedź zadziała, jeśli chcesz uzyskać losowy wiersz dla określonego klawisza skrótu. jeśli chcesz dostać "globalny" element losowy, to nie zadziała :( –

3

Naiwny sposobem byłoby 1) używać opisać połączenia tabeli aby dostać N (całkowita liczba wierszy) w tabeli 2) wybrać liczbę losową I między 1 i N 3) skanowania. Zatrzymaj się, dopóki nie zobaczysz, że się wierci

Zastanawiam się nad lepszym sposobem na zrobienie tego. Będę aktualizował, kiedy mam dobrą odpowiedź.

12

Jeśli używasz GUID jako klawisz krzyżyka na stole, można zrobić coś takiego:

var client = new AmazonDynamoDBClient(); 

var lastKeyEvaluated = new Dictionary<string, AttributeValue>() 
{ 
    { "YOUR_HASH_KEY", new AttributeValue(Guid.NewGuid().ToString()) } 
}; 

var request = new ScanRequest() 
{ 
    TableName = YOUR_TABLE_NAME, 
    ExclusiveStartKey = lastKeyEvaluated, 
    Limit = 1 
}; 
var response = client.Scan(request); 

To daje losowo rekord za każdym razem, ponieważ generuje losowy identyfikator GUID jako lastKeyEvaluated .

+2

Więc ustawiając limit na 1, otrzymasz tylko jeden przedmiot, ale jak ustawić ExclusiveStartKey na losowy UUID, który nie istnieje ale dajesz kolejny losowy wiersz ??Czy ten wygenerowany identyfikator UUID nie musi już istnieć w tabeli? A dzięki swojej wyjątkowości to się nigdy nie wydarzy. –

+0

Identyfikator UUID nie musi istnieć w tabeli. Dla danego klucza DynamoDB wie, gdzie powinien "istnieć", jeśli tak. Gdy wybierzesz losową, DynamoDB rozpoczyna się w tej lokalizacji, a następnie przechodzi do następnego elementu i zwraca go. Jest to podobne do znalezienia losowego domu na ulicy: wybierz numer domu, przejdź do miejsca, w którym powinien być ten numer domu, a następnie przejdź ulicą, aż znajdziesz prawdziwy dom. – Trenton

+0

Ponadto wartość YOUR_HASH_KEY można uogólnić na wybieranie 2048 losowych bitów, traktując to jak ciąg i używając go jako punktu wyjścia. Zobacz https://stackoverflow.com/questions/5351277/, jak to zrobić w Javie. – Trenton

Powiązane problemy