我正在使用DynamoDB作为我的移动应用程序的后端数据库,并且架构等在Android和Android之间是相同的。 iOS版。对于特定用例,我必须基于两个未编制索引的属性执行扫描。对于iOS Objective C,我使用以下代码:
AWSDynamoDBScanExpression *scanExpression = [AWSDynamoDBScanExpression new];
scanExpression.limit = [NSNumber numberWithInt:maxCount];
scanExpression.filterExpression = @"#l = :location AND event = :event";
scanExpression.expressionAttributeNames = @{@"#l":@"location"};
scanExpression.expressionAttributeValues = @{@":location":location,
@":event":EVENT_TASTING};
位置和事件都是字符串。 EVENT_TASTING是一个String常量。此扫描保持返回零结果,即使我已经验证了所提供的条目我应该接收结果。我在Android Java中使用以下代码:
DynamoDBScanExpression scanExpression = new DynamoDBScanExpression();
scanExpression.setLimit(maxCount);
scanExpression.addFilterCondition("location",
new Condition()
.withComparisonOperator(ComparisonOperator.EQ)
.withAttributeValueList(new AttributeValue().withS(location)));
scanExpression.addFilterCondition("event",
new Condition()
.withComparisonOperator(ComparisonOperator.EQ)
.withAttributeValueList(new AttributeValue().withS(Constants.EVENT_TASTING)));
扫描在Android中按预期工作。在iOS中需要改变什么才能使它在那里工作?我将iOS SDK更新到2.3.6,但它没有什么区别。这是我在代码中进行的唯一扫描操作。
我的scanExpression for iOS是否有错误?有没有办法可以使用Android风格的语法在iOS上运行?
更新
我尝试了以下更改:
AWSDynamoDBScanExpression *scanExpression = [AWSDynamoDBScanExpression new];
AWSDynamoDBAttributeValue *locationVal = [AWSDynamoDBAttributeValue new];
locationVal.S = location;
AWSDynamoDBAttributeValue *eventVal = [AWSDynamoDBAttributeValue new];
eventVal.S = EVENT_TASTING;
scanExpression.limit = [NSNumber numberWithInt:maxCount];
scanExpression.filterExpression = @"#l = :location AND event = :event";
scanExpression.expressionAttributeNames = @{@"#l":@"location"};
scanExpression.expressionAttributeValues = @{@":location":locationVal,
@":event":eventVal};
但现在我收到一个错误:
The request failed. Error: [Error Domain=com.amazonaws.AWSDynamoDBErrorDomain Code=0 "(null)" UserInfo={message=ExpressionAttributeValues contains invalid value: Supplied AttributeValue is empty, must contain exactly one of the supported datatypes for key :location, __type=com.amazon.coral.validate#ValidationException}]
答案 0 :(得分:1)
感谢来自@YosukeMatsuda的提示,我可以通过重复调用Scan来解决这个问题,直到LastEvaluatedKey为空。我将此作为答案发布,因为不幸的是,迈克的回答并未指出正确的问题并且具有误导性。
以下是我如何更改iOS中的代码:
// In a different method (for first call):
AWSDynamoDBScanExpression *scanExpression = // See code in original question
// In a new method that can be called recursively:
// DynamoDBObjectMapper scan:class-for-model expression:scanExpression
// continueWithBlock -> if (task.result):
AWSDynamoDBPaginatedOutput *paginatedOutput = task.result;
if (paginatedOutput.items.count != 0)
// Append the paginatedOutput.items to the cumulative array
else
// Replace the cumulative array with paginatedOutput.items
if (paginatedOutput.lastEvaluatedKey.count == 0) {
// Scan is complete - handle results
} else {
// Check if you have sufficient results
// In my case I had asked for 25 results but was getting 39
// So it doesn't seem to obey the scanExpression.limit value
// If more results are needed, continue the scan
[scanExpression setExclusiveStartKey:paginatedOutput.lastEvaluatedKey];
// Call this method recursively
}
如果有更优雅的解决方案,我很乐意听到它。但至少它现在有效。
答案 1 :(得分:0)
您使用的Android代码与ObjectiveC版本之间存在一些差异。
loginBehaviour FBSDKLoginBehaviorSystemAccount
和location
的值应为event
类型,而不是字符串;如果您进行此更改,您的查询很可能会开始工作。我希望这可以回答你的问题,但不能确定,因为你只是说"这在Android中可以正常运行 - 我怎样才能让它在iOS" 中运行但是你并没有告诉我们什么是破碎的。