Как запрашивать и упорядочивать по двум отдельным ключам сортировки в DynamoDB?

#amazon-dynamodb

#amazon-dynamodb

Вопрос:

 GROUPS
    userID: string
    groupID: string
    lastActive: number
    birthday: number
  

Предположим, у меня есть таблица DynamoDB с именем GROUPS, в которой хранятся элементы с этими атрибутами. В таблице записывается, какие пользователи присоединены к каким группам. Пользователи могут находиться в нескольких группах одновременно. Поэтому составной первичный ключ чаще всего будет:

 partition key: userID
sort key: groupID
  

Однако, если бы я хотел запросить для всех пользователей в определенной группе, в пределах определенного диапазона дней рождения, отсортированных по lastActive , возможно ли это, и если да, то какой индекс мне нужно создать?

Могу ли я синтезировать lastActive и userID создать синтетический ключ сортировки, например:

 GROUPS
    groupID: string
    lastActiveUserID: string (i.e. "20201230T09:45:59-abc123")
    birthday: number
  

Что привело бы к созданию другого составного первичного ключа, в котором есть ключ раздела groupID и ключ сортировки lastActiveUserID , который сортировал бы участников по тому, когда они были активны в последний раз, а затем вторичный индекс для фильтрации по дню рождения?

Ответ №1:

Как написано, нет, это невозможно.

в пределах определенного диапазона дней рождения

подразумевает sk_birthday between :start and :end

сортировка по lastActive

подразумевает lastActive в качестве ключа сортировки.

которые являются взаимоисключающими…Я не могу разработать ключ сортировки, который мог бы содержать оба значения в удобном формате.

У вас может быть глобальный вторичный индекс с хэш-ключом group-id и lastActive в качестве ключа сортировки, а затем фильтровать по дню рождения. Но это влияет только на возвращаемые данные, это не влияет ни на считываемые данные, ни на стоимость чтения этих данных. Кроме того, поскольку DDB считывает только 1 МБ данных за раз, вам придется вызывать его повторно в цикле, если возможно, что данная группа насчитывает более 1 МБ членов.

Кроме того, когда ваш индекс имеет другой ключ раздела (хэш), чем ваша таблица, это глобальный вторичный индекс (GSI). Если ваш индекс имеет тот же ключ раздела, но другой ключ сортировки, чем у таблицы, это можно сделать с помощью локального вторичного индекса (LSI)

Однако для любого заданного запроса вы можете использовать только таблицу или заданный индекс. Вы не можете использовать несколько индексов одновременно

Теперь, сказав все это, что именно вы подразумеваете под «определенным диапазоном дней рождения», если рассматриваемый диапазон представляет собой определенный период, по месяцам, по неделям. Возможно, у вас может быть GSI, где хэш-ключ "group-id#birthday-period" , а ключ сортировки lastActive

Так, например, запрос «дайте мне дни рождения ГРУППЫ на следующий месяц»
(hs = «GROUPA #НОЯБРЬ»)

Но если вы хотите ноябрь и декабрь, вам нужно будет выполнить два запроса и объединить и отсортировать результаты самостоятельно.

Эффективное и эффективное использование DDB означает избегать Scan() и избегать использования filterExpressions того, что, как вы знаете, приведет к потере большого количества прочитанных данных.

Комментарии:

1. Вы не только ответили на мой вопрос, но и на последующие действия, которые я ожидал задать. Я полагаю, тогда только непосредственные обходные пути — это либо чрезмерный запрос и фильтрация на клиенте, либо использование поисковой системы, такой как Algolia или Elasticsearch… прекрасно.

2. Да, поиск в DDB — это не весело. Elasticsearch спереди в DDB является распространенным решением. Но ES стоит недешево. Возможно, лучше посмотреть на Aurora.