2016-04-18 105 views
0

我正在使用DynamoDB作爲我的移動應用程序的後端數據庫,並且架構等在iOS中完全相同。對於特定的用例,我必須根據兩個未編制索引的屬性執行掃描。對於iOS Objective C,我使用以下代碼:AWS DynamoDB在iOS上掃描失敗,但在Android上工作

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,但它沒有什麼區別。這是我在我的代碼中唯一的掃描操作。

我的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}] 

回答

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 
} 

如果有一個更優雅的解決方案,我很樂意聽到它。但至少現在起作用了。

0

有Android的代碼,你之間有一些差異使用和ObjectiveC版本。

    在Android版本
  1. 你使用的是舊篩選條件 API而在的ObjectiveC你使用更現代化的篩選表達式 API;這並不一定會使較新的失敗,但它只是指出
  2. 在ExpressionAttributeValues的情況下,您傳入的locationevent的值應該是AWSDynamoDBAttributeValue *而不是字符串;如果您進行此更改,您的查詢很可能開始工作。

我希望這回答了你的問題,但不能肯定,因爲你只說「這個工程預期在Android的 - 我怎樣才能使它在iOS的工作」但你沒有告訴我們什麼地方不對頭。

+0

正如我所提到的:「即使我已驗證所提供的條目我應該收到結果,此掃描仍然返回零結果。」是的,我使用舊的過濾條件,因爲Android支持它,但iOS不。 – LNI

+0

你仍然需要提供如何實例化'location'和'event'。此外,[打開詳細日誌記錄](http://docs.aws.amazon.com/mobile/sdkforios/developerguide/setup.html)並使用請求JSON更新問題。 –

+0

使用詳細日誌記錄選項的輸出更新了問題。事件和位置都是字符串。以上輸出顯示它們正確設置。如果在使用DynamoDB控制檯的查詢中對事件和位置使用相同的值,則掃描會成功返回值。 – LNI

相關問題