我想问一下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
是最好的变体思考。
表的结构
#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
是空的 - 我做的都是正确的吗?
答案 0 :(得分:1)
您确定要使用扫描表达式吗?这确实消耗了大量的读取容量并且可以破坏你的动力学表现:扫描会读取整个表格,只有这样才能应用过滤器并返回值。
如果您向我们提供您的实际动态表结构,我们可以讨论另一种解决方案。例如,一个解决方案可能是创建一个全局二级索引(如果最终一致的读取对你来说可行)或一个本地二级索引(及其限制),并在你的值上使用范围键来过滤。这将允许您使用查询,这是更好的,并建议最佳做法。
话虽如此,你可以使用AND和OR运算符为过滤器添加条件,导致类似于&#34; #P =:val1或#P =:val2&#34;
希望有所帮助