Mister_L
Mister_L

Reputation: 2611

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.

Upvotes: 8

Views: 16235

Answers (3)

cloudlena
cloudlena

Reputation: 885

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

FilterExpression = 'attribute_exists(#0.#1)',
ExpressionAttributeNames = {
    "#0": "appsMap",
    "#1": "qa-app"
},
ProjectionExpression  = "deviceID"

Upvotes: 4

Dmitry Buslaev
Dmitry Buslaev

Reputation: 300

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.

Upvotes: 5

Mike Dinescu
Mike Dinescu

Reputation: 55720

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.

Upvotes: 2

Related Questions