在非键属性上查询 DynamoDB

Querying DynamoDB on non-key attributes

是否可以在 AWS 版本 2 中使用非键属性过滤 DynamoDB 查询?亚马逊说他们可以做到:http://amzn.to/1FVgQ9B。但是他们也给API吗?我找到了 AWSDynamoDBQueryExpression,但我认为它只允许对范围键进行过滤(没有足够的文档)。我正在 iOS 和 AWS 版本 2 中寻找合适的 API。谢谢!

我正在回答我自己的问题。这也是我在 AWS 支持论坛上发布的内容:

您无法使用高级 API -- AWSDynamoDBObjectMapper 执行此操作。使用AWSDynamoDBObjectMapper时,需要向查询方法提供一个AWSDynamoDBQueryExpression对象来指定查询条件。 AWSDynamoDBQueryExpression 没有为您提供在非键属性上设置过滤器(条件)的选项。我想知道为什么不支持这个!但是,AWSDynamoDBScanExpression 允许您在使用扫描方法时指定非键属性的条件。但是当你真正的意思是查询时,你不想扫描。

幸运的是,您可以使用低级别 API 执行此操作,方法是直接调用 AWSDynamoDB 上的查询,提供 AWSDynamoDBQueryInput,它允许您指定大量低级别参数。 AWSDynamoDBQueryInput 允许您使用 queryFilter 或 filterExpression 指定非键属性的过滤条件。 queryFilter 已弃用,建议使用 filterExpression。 以下是帮助我解决这个问题的两个文件:

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

这是 swift 中的代码示例。在此代码中,我根据非关键属性 "approved" 字段进行过滤。 recId为主键:

    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

        }

    }