Как фильтровать (сканировать) сопоставленные списки из 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"

Надеюсь, поможет.

Другие вопросы по тегам