Как фильтровать (сканировать) сопоставленные списки из DynamoDB
Это моя структура БД
{
"Accounts": [
{
"accountId": "12345",
"region": "us-east-1"
}
],
"createdBy": "abcd@gmail.com",
}
У меня есть несколько рядов аналогичной структуры. Мне нужно отфильтровать счета по регионам. Может кто-нибудь помочь мне с фильтром Expression для сканирования? Любая помощь будет оценена.
1 ответ
{
{
"Accounts": [
{
"accountId": "12345",
"region": "us-east-1"
},
],
"createdBy": "abcd@gmail.com",
},
{
"Accounts": [
{
"accountId": "98765",
"region": "us-west-1"
},
{
"accountId": "45678",
"region": "eu-west-2"
}
],
"createdBy": "pqrs@gmail.com",
},
}
Я предполагаю, что это данные вашей таблицы, когда в вашей таблице присутствуют два элемента (только предположение, сообщите мне, если я ошибаюсь). Во-первых, если ваша таблица содержит такие элементы, и вам нужно отфильтровать "Счета" по каждому элементу, который находится в определенном регионе, то это невозможно, потому что вы запрашиваете только часть элемента, и в действительности, когда вы сканируете таблицу с помощью filterExpressions, она не возвращает вам часть Item, она возвращает вам весь Item в зависимости от вашего выражения фильтра. Тем не менее я постараюсь объяснить, как вы можете заставить его работать.
Поскольку каждый элемент вашей таблицы содержит ключ "Счета", в качестве значения которого используется список. Вы можете использовать выражение "filterAttribute", но только для списков, содержащих строковые значения, что-то вроде ниже
{
"movie": "XYZ",
"country": "India",
"information": {
"actors": [
"ABC"
],
"genres": [
"Action"
"Romance",
"Drama",
]
}
}
Для этого вы можете использовать что-то вроде
response = table.scan(
FilterExpression=Attr('information.genres').eq('Romance')
)
Но так как в вашем случае список содержит больше объектов, невозможно напрямую сканировать с использованием любого выражения фильтра. Вы должны реструктурировать свою базу данных таким образом, чтобы можно было применить фильтр для сканирования или вы можете отсканировать всю таблицу в одном объекте, а затем использовать функции языка программирования для фильтрации данных из вашего объекта данных.
Для реструктуризации я бы предложил вам небольшое изменение, которое будет полезно, поскольку ваш ключ "Аккаунты" - это список, содержащий объекты, которые имеют два поля "accountId" и "region". Вы можете изменить тип ключа "Учетные записи" для объекта, и внутри этого объекта поддерживать два списка, один для "accountId" и один для "регионов", что-то вроде ниже:
{
"Accounts": {
"accountId": ["12345", "23456", "98765"],
"region": ["us-east-1", "us-west-1", "eu-west-1"]
},
"createdBy": "abcd@gmail.com",
}
Теперь у вас есть два списка, поэтому для accountId[0] ваш регион будет присутствовать в region[0] вот так. Теперь вы можете сканировать, используя выражение фильтра, как показано ниже,
response = table.scan(
FilterExpression=Attr('Accounts.region').contains('us-west-1')
)
Таким образом, это вернет вам элементы, которые имеют по крайней мере учетную запись в us-west-1, но все же вам нужно отфильтровать ее для получения только тех учетных записей, которые находятся в "us-west-1"
Надеюсь, поможет.