DynamoDB query on non-key attributes

Can you filter DynamoDB queries using non-key attributes in AWS V2? Amazon says they can do it: http://amzn.to/1FVgQ9B . But do they provide APIs as well? I found AWSDynamoDBQueryExpression, but I think it only allows the range key to be filtered (not enough documentation). I'm looking for a suitable API in iOS and AWS version 2. Thank you!

+3


source to share


1 answer


I am answering my own question. This is what I posted on the AWS support forum:

You cannot do this with a high level API - AWSDynamoDBObjectMapper. When using AWSDynamoDBObjectMapper, you need to provide an AWSDynamoDBQueryExpression object for the query method to specify the query conditions. AWSDynamoDBQueryExpression does not give you the ability to set filters (conditions) on non-key attributes. I wonder why this is not supported! However, AWSDynamoDBScanExpression allows you to specify conditions for non-key attributes when using the scan method. But you don't want to crawl when you actually mean a request.

Fortunately, you can do this using a low-level API, making a direct call to AWSDynamoDB, providing AWSDynamoDBQueryInput that allows you to specify a lot of low-level parameters. AWSDynamoDBQueryInput allows you to specify filter conditions for non-key attributes using either queryFilter or filterExpression. queryFilter is deprecated, filterExpression is recommended. Here are two documents that helped me figure it out:



http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html http://docs.aws.amazon.com/AWSiOSSDK/latest/Classes/AWSDynamoDBQueryInput.html

Here is some sample code in swift. In this code, I am filtering based on the "approved" field, which is a non-key attribute. recId is the primary key:

    func getApprovedRecords(recId: Int) {



     let dynamoDB = AWSDynamoDB.defaultDynamoDB()

        var startKey = nil

        var queryInput = AWSDynamoDBQueryInput()

        queryInput.tableName = TABLE_NAME

        queryInput.limit = QUERY_SIZE

        queryInput.exclusiveStartKey = startKey



        var recIdValue = AWSDynamoDBAttributeValue()

        recIdValue.N = String(recId)

        var recIdCondition = AWSDynamoDBCondition()

        recIdCondition.comparisonOperator = AWSDynamoDBComparisonOperator.EQ

        recIdCondition.attributeValueList = [recIdValue]



        queryInput.keyConditions = [ "recId"\" : recIdCondition]


        var oneValue = AWSDynamoDBAttributeValue()

        oneValue.N = "1"



        queryInput.expressionAttributeValues = [ ":one" : oneValue ]    

        queryInput.filterExpression = "approved = :one"

        dynamoDB.query(queryInput).continueWithBlock { (task: BFTask!) -> AnyObject! in

            if ((task.error) != nil) {

                NSLog("The request failed. Error: \(task.error)")

            }

            if ((task.exception) != nil) {

                NSLog("The request failed. Exception: \(task.exception)")

            }

            if ((task.result) != nil) {

                NSLog("The request  succeeded.")

                let results = task.result as! AWSDynamoDBQueryOutput

                for r in results.items {

                    // do whatever with the result

                }

            }

            return nil

        }

    }

      

+5


source







All Articles