繁体   English   中英

AWS DynamoDB Scan在iOS上失败但在Android上工作

[英]AWS DynamoDB Scan failing on iOS but works on Android

我将DynamoDB用作移动应用程序的后端数据库,并且架构等在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是一个字符串常量。 即使我已经验证了所提供的条目我应该收到的结果,该扫描仍返回零结果。 我在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,但没有任何改变。 这是我在代码中执行的唯一扫描操作。

iOS的scanExpression是否存在错误? 有没有一种方法可以使用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}]

感谢@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
}

如果有更优雅的解决方案,我很想听听。 但是至少现在可以了。

您使用的Android代码与ObjectiveC版本之间存在一些差异。

  1. 在Android版本中,您使用的是较旧的Filter Condition API;而在ObjectiveC中,您使用的是较现代的Filter Expression API; 这并不一定会使新的失败,但这只是需要指出的一点
  2. 对于ExpressionAttributeValues,您要传递的locationevent的值应为AWSDynamoDBAttributeValue *类型,而不是字符串; 如果进行此更改,您的查询很可能会开始工作。

我希望这能回答您的问题,但不能确定,因为您只说“这在Android中可以按预期工作-我如何使其在iOS中工作”,但您没有告诉我们有什么问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM