在非关键属性上查询DynamoDB

时间:2022-04-06 07:37:17

Is it possible to filter DynamoDB queries using non-key attributes in AWS version 2 ? Amazon says that they can do it: http://amzn.to/1FVgQ9B. But do they also give the API? I found AWSDynamoDBQueryExpression, but I think it only lets filtering on the range key (not enough documentation). I'm looking for the proper API in iOS and AWS version 2. Thanks!

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

1 个解决方案

#1


I'm answering my own question. This is what I posted on AWS support forum as well:

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

You can't do this with the high level API -- AWSDynamoDBObjectMapper. When using AWSDynamoDBObjectMapper, you need to provide an AWSDynamoDBQueryExpression object to the query method to specify the query conditions. AWSDynamoDBQueryExpression doesn't give you the option to set filters(conditions) on non-key attributes. I wonder why this isn't supported! However, AWSDynamoDBScanExpression lets you specify conditions on non-key attributes when you use the scan method. But you don't want to scan when you actually mean a query.

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

Fortunately, you can do this using the low level API by directly calling query on AWSDynamoDB providing an AWSDynamoDBQueryInput which lets you specify a lot of low level parameters. AWSDynamoDBQueryInput lets you specify the filter conditions on non-key attributes using either queryFilter or filterExpression. queryFilter is deprecated, it's recommended to use filterExpression. Here are the two documents that helped me to figure this out:

幸运的是,您可以使用低级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

Here's a code example in swift. In this code I'm filtering based on "approved" field that is a non-key attribute. recId is the primary key:

这是swift中的代码示例。在此代码中,我基于“已批准”字段进行过滤,该字段是非关键属性。 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

        }

    }

#1


I'm answering my own question. This is what I posted on AWS support forum as well:

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

You can't do this with the high level API -- AWSDynamoDBObjectMapper. When using AWSDynamoDBObjectMapper, you need to provide an AWSDynamoDBQueryExpression object to the query method to specify the query conditions. AWSDynamoDBQueryExpression doesn't give you the option to set filters(conditions) on non-key attributes. I wonder why this isn't supported! However, AWSDynamoDBScanExpression lets you specify conditions on non-key attributes when you use the scan method. But you don't want to scan when you actually mean a query.

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

Fortunately, you can do this using the low level API by directly calling query on AWSDynamoDB providing an AWSDynamoDBQueryInput which lets you specify a lot of low level parameters. AWSDynamoDBQueryInput lets you specify the filter conditions on non-key attributes using either queryFilter or filterExpression. queryFilter is deprecated, it's recommended to use filterExpression. Here are the two documents that helped me to figure this out:

幸运的是,您可以使用低级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

Here's a code example in swift. In this code I'm filtering based on "approved" field that is a non-key attribute. recId is the primary key:

这是swift中的代码示例。在此代码中,我基于“已批准”字段进行过滤,该字段是非关键属性。 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

        }

    }