DynamoDb: как получить первый элемент (по ключу сортировки) для каждого из заданного списка ключей раздела - PullRequest
2 голосов
/ 10 января 2020

У меня есть таблица DynamodB, в которой хранятся исторические данные о прогонах для процессов, которые выполняются на моем сервере, мне нужно место, где я могу агрегировать эти процессы и просматривать данные для каждого из них. Каждый процесс имеет свой собственный ProcessId, который является ключом раздела для таблицы DynamodB. Ключом сортировки является StartDateTime

{
  ProcessId, // Partition Key
  StartDateTime, // Sort Key
  ... // More data
}

. По сути, мне нужно получить самый последний StartDateTime для каждого предоставленного мной ProcessId. Я использую nodejs лямбда с aws -sdk для получения данных. Я рассмотрел использование BatchGetItem, но, насколько я понимаю, для таблиц с ключом раздела и ключом сортировки вам необходимо предоставить оба варианта для получения элемента. Я также изучил использование запроса, но мне нужно было бы выполнить отдельный запрос для каждого раздела, который меньше идеального. Кто-нибудь знает, как я могу сделать этот запрос за один вызов, вместо того, чтобы делать отдельный вызов на раздел?

Ответы [ 2 ]

1 голос
/ 13 января 2020

Подводя итог тому, что я понял из вашего поста, вы можете иметь в своей таблице такие данные:

PK (id)         SK (timestamp)    Other data
process1        1                 ...
process2        4                 ...
process1        8                 ...
process3        18                ...
process2        25                ...

Вам нужно легко получить:

process1        8                 ...
process2        25                ...
process3        18                ...

Как сказал sandboxbohemian Я предлагаю вам поток для запуска лямбда-функции каждый раз, когда поступает новый вход. Однако я бы использовал ту же таблицу и вставил бы элемент с тем же идентификатором и временной меткой, равной 0. Кроме того, я добавляю двоичный атрибут «latest», для которого всегда установлено значение «True», и числовой атрибут для текущей временной метки. Хронологически записи будут выглядеть следующим образом:

PK (id)         SK (timestamp)    Other data      timestamp2(GSI SK)  latest (GSI PK)
process1        1                 ...                      
process1        0                 ...             1                   true
process2        4                 ...                      
process2        0                 ...             4                   true
process1        8                 ...                      
process1        0                 ...             8        
process3        18                ...                      
process3        0                 ...             18                  true       
process2        25                ...                      
process2        0                 ...             25                  true       

Затем необходимо создать GSI с PK, равным «последнему» и SK, равным «отметке времени» и атрибутам «id» и «data» проекта. Это будет разреженный индекс, означающий, что будет присутствовать только элемент с последним заполненным атрибутом. Вот после это содержание:

latest (GSI PK) timestamp2 (GSI SK)   id        timestamp   Data
true            8                     process1  0           ...
true            25                    process2  0           ...    
true            18                    process3  0           ...   

Как видите, PK всегда имеет одинаковое значение. Поэтому он позволяет выполнять запрос или сканирование. Если вам нужен весь последний процесс, вы можете сделать сканирование. Если число процессов действительно велико, вы можете сделать запрос с последним = True и воспользоваться возможностями сортировки по отметке времени 2.

Я согласен, что эта схема не является интуитивно понятной, но часто это происходит с DynamodB

0 голосов
/ 10 января 2020

Похоже, что вы пытаетесь выполнить своего рода агрегацию, и DynamoDB обычно не лучше всего подходит для агрегации, но больше подходит для операций в стиле CRUD.

Вместо выполнения дорогостоящих запросов или сканирований, попробуйте включить DynamoDB Streams на таблицу и использование другой лямбды для «вставки» времени начала в другую таблицу DynamoDB с идентификатором процесса в качестве ключа раздела.

Затем вы можете выполнить запрос на самое позднее время запуска для идентификатора процесса в этой новой таблице. .

...