简体   繁体   中英

How to filter (Scan) mapped lists from DynamoDB

This is my db structure

{
  "Accounts": [
   {
     "accountId": "12345",
     "region": "us-east-1"
   }
  ],
  "createdBy": "abcd@gmail.com",
}

I have several rows of similar structure. I need to filter the accounts based on the regions. Can anyone help me with the filterExpression for the scan? Any help would be appreciated.

{
      {
         "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",
      },
}

I assume this is your table's data when two items (just an assumption, inform me if I am wrong) are present in your table. First thing is that if your table contains items like this and you need to filter out "Accounts" from each item which are in a particular region, then it is not possible because you are asking for only a part of an Item and in reality when you scan a table using filterExpressions, it doesn't return you a part of an Item, it will return you a whole Item depending on you filter-expression. Still I will try to explain how you can make it work.

As each item from your table contains a "Accounts" key which has a list as value. You can do use a contains filterAttribute expression, but then that is only for lists containing string values, something like below

{
    "movie": "XYZ",
    "country": "India",
    "information": {
        "actors": [
            "ABC"
        ],
        "genres": [
            "Action"
            "Romance",
            "Drama",
        ]
    }
}

For this you can use something like

response = table.scan(
    FilterExpression=Attr('information.genres').eq('Romance')
)

But as in your case the list contains more objects, it is not directly possible to scan using any filter expression. You have to restructure your database in a fashion that you can apply filter to scan or you can scan the whole table in a single object and then use your programming language's features to filter out the data from your data object.

For restructuring I would suggest you a small change which will be helpful, as your "Accounts" key is a list having objects which have two fields "accountId" and "region". You can change type of "Accounts" key to an object and inside that object maintain two lists, one for "accountId"s and one for "regions"s, Something like below:

{
      "Accounts": {
         "accountId": ["12345", "23456", "98765"],
         "region": ["us-east-1", "us-west-1", "eu-west-1"]
      },
      "createdBy": "abcd@gmail.com",
 }

Now you have two lists, so for accountId[0], your region will be present in region[0] like that. Now you can scan using filter expression like below,

response = table.scan(
        FilterExpression=Attr('Accounts.region').contains('us-west-1')
    )

So this will return you the items which have atleast an account in us-west-1 but still you need to filter it out for getting only the accounts which are in "us-west-1"

Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM