Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dynamodb - scan items where map contains a key

I have a table that contains a field (not a key field), called appsMap, and it looks like this:

appsMap = { "qa-app": "abc", "another-app": "xyz" }

I want to scan all rows whose appsMap contains the key "qa-app" (the value is not important, just the key). I tried something like this but it doesn't work in the way I need:

    FilterExpression = '#appsMap.#app <> :v',
    ExpressionAttributeNames = {
        "#app": "qa-app",
        "#appsMap": "appsMap"
    },
    ExpressionAttributeValues = {
        ":v": { "NULL": True }
    },
    ProjectionExpression  = "deviceID"

What's the correct syntax?

Thanks.

like image 506
Mister_L Avatar asked Mar 22 '16 11:03

Mister_L


People also ask

What is the use of Scan item option in DynamoDB?

A Scan operation in Amazon DynamoDB reads every item in a table or a secondary index. By default, a Scan operation returns all of the data attributes for every item in the table or index. You can use the ProjectionExpression parameter so that Scan only returns some of the attributes, rather than all of them.

Which API call would you use to Query an item by its primary key?

With the DynamoDB API, you use the PutItem operation to add an item to a table. DynamoDB provides the GetItem action for retrieving an item by its primary key.

Can you Query on sort key DynamoDB?

You can Query any table or secondary index, provided that it has a composite primary key (partition key and sort key). Query operations consume read capacity units, as follows. The table's provisioned read capacity. The index's provisioned read capacity.

What is difference between Scan and Query in DynamoDB?

DynamoDB supports two different types of read operations, which are query and scan. A query is a lookup based on either the primary key or an index key. A scan is, as the name indicates, a read call that scans the entire table in order to find a particular result.


3 Answers

There is a discussion on the subject here: https://forums.aws.amazon.com/thread.jspa?threadID=164470

You might be missing this part from the example: ExpressionAttributeValues: {":name":{"S":"Jeff"}}

However, just wanted to echo what was already being said, scan is an expensive procedure that goes through every item and thus making your database hard to scale.

Unlike with other databases, you have to do plenty of setup with Dynamo in order to get it to perform at it's great level, here is a suggestion: 1) Convert this into a root value, for example add to the root: qaExist, with possible values of 0|1 or true|false. 2) Create secondary index for the newly created value. 3) Make query on the new index specifying 0 as a search parameter.

This will make your system very fast and very scalable regardless of how many records you get in there later on.

like image 56
Dmitry Buslaev Avatar answered Sep 20 '22 20:09

Dmitry Buslaev


If I understand the question correctly, you can do the following:

FilterExpression = 'attribute_exists(#0.#1)',
ExpressionAttributeNames = {
    "#0": "appsMap",
    "#1": "qa-app"
},
ProjectionExpression  = "deviceID"
like image 35
cloudlena Avatar answered Sep 18 '22 20:09

cloudlena


Since you're not being a bit vague about your expectations and what's happening ("I tried something like this but it doesn't work in the way I need") I'd like to mention that a scan with a filter is very different than a query.

Filters are applied on the server but only after the scan request is executed, meaning that it will still iterate over all data in your table and instead of returning you each item, it applies a filter to each response, saving you some network bandwidth, but potentially returning empty results as you page trough your entire table.

You could look into creating a GSI on the table if this is a query you expect to have to run often.

like image 25
Mike Dinescu Avatar answered Sep 18 '22 20:09

Mike Dinescu