通过值数组筛选的多个项目的AWS Batch请求

时间:2016-04-18 08:18:26

标签: ios objective-c amazon-dynamodb amazon

我想问一下AWSDynamoDBScanExpression的filterExpression。 问题:

我想在一个表中扫描数据库中的所有对象,其中一个参数(让我们称之为uniqueId)是存储在数组中的值之一(所需的uniqueIds数组)。

对于一个对象 - 使用

很容易
AWSDynamoDBScanExpression *scanExpression = [[AWSDynamoDBScanExpression alloc] init];
scanExpression.expressionAttributeNames = @{
                                            @"#P": [NSString stringWithFormat:@"%@", property]
                                            };
scanExpression.filterExpression =@"#P = :val";
scanExpression.expressionAttributeValues = @{
                                             @":val" : @"some uniqueID"
                                             };

所以在同样的逻辑中我想扫描数据库中的多个对象

 AWSDynamoDBScanExpression *scanExpression = [[AWSDynamoDBScanExpression alloc] init];
scanExpression.expressionAttributeNames = @{
                                            @"#P": [NSString stringWithFormat:@"%@", property]
                                            };
scanExpression.filterExpression = <WHAT SHOULD BE HERE, WHAT EXPRESSION>;
scanExpression.expressionAttributeValues = @{
                                             @":val" : [@"some unique id 1", 
                                             @"some unique id 2",
                                             @"some unique id 3"]
                                             };

有没有办法改变scanExpression.filterExpression来实现这个目标?

编辑1

不,我不确定scan是否是最佳解决方案。实际上query是最好的变体思考。

表的结构

enter image description here

  

#P = :val1 OR #P = :val2   有意义

EDIT2

这是一些更新:

AWSDynamoDBQueryExpression *query = [[AWSDynamoDBQueryExpression alloc] init];
NSMutableDictionary *dictionaryAttributes = [[NSMutableDictionary alloc] init];
NSString *expression = @"";
for (int i = 0; i < filteredHashValues.count; i++) {
    NSString *variableName = [NSString stringWithFormat:@":val%i", i];
    [dictionaryAttributes setValue:filteredHashValues[i] forKey:variableName];
    expression = [expression stringByAppendingString:expression.length ? [NSString stringWithFormat:@"OR #P = %@ " , variableName] : [NSString stringWithFormat:@"#P = %@ " , variableName]];
}

query.indexName = @"uniqueId-index";
query.expressionAttributeNames = @{
                                   @"#P": [NSString stringWithFormat:@"%@", @"uniqueId"]
                                   };
query.filterExpression = expression;
query.expressionAttributeValues = dictionaryAttributes;

AWSDynamoDBObjectMapper *dynamoDBObjectMapper = [AWSDynamoDBObjectMapper defaultDynamoDBObjectMapper];
[[dynamoDBObjectMapper query:className expression:query] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) {

    if (task.result) {
        AWSDynamoDBPaginatedOutput *output = task.result;
    }
    return nil;
}];

但结果

  

打印表达说明:   #P = :val0 OR #P = :val1 OR #P = :val2 OR #P = :val3

     

打印dictionaryAttributes的描述:     { ":val0" = "8A93A3EA-9FB9-4396-BBF6-D0BD3CBE6BE5"; ":val1" = "08533EBA-D3E5-406C-8CDE-03EECCCA801B"; ":val2" = "954AE402-336E-423D-BF03-7E8AED1446FE"; ":val3" = "F683BDF8-0507-4218-9927-9F14D470E593"; }

     

打印任务说明 - &gt; _error:错误   `Domain = com.amazonaws.AWSDynamoDBErrorDomain Code = 0“(null)”   的UserInfo = {__类型= com.amazon.coral.validate#ValidationException,   message = ExpressionAttributeValues包含无效值:提供   AttributeValue为空,必须包含其中一个支持的   key的数据类型:awsddbomhashvalueplaceholder}

看起来ExpressionAttributeValues是空的 - 我做的都是正确的吗?

1 个答案:

答案 0 :(得分:1)

您确定要使用扫描表达式吗?这确实消耗了大量的读取容量并且可以破坏你的动力学表现:扫描会读取整个表格,只有这样才能应用过滤器并返回值。

如果您向我们提供您的实际动态表结构,我们可以讨论另一种解决方案。例如,一个解决方案可能是创建一个全局二级索引(如果最终一致的读取对你来说可行)或一个本地二级索引(及其限制),并在你的值上使用范围键来过滤。这将允许您使用查询,这是更好的,并建议最佳做法。

话虽如此,你可以使用AND和OR运算符为过滤器添加条件,导致类似于&#34; #P =:val1或#P =:val2&#34;

希望有所帮助