2016-04-18 16 views
0

私はモバイルアプリケーションのバックエンドデータベースとしてDynamoDBを使用していますが、スキーマなどはAndroid & iOSで同じです。特定のユースケースでは、インデックスが作成されていない2つの属性に基づいてスキャンを実行する必要があります。 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にアップデートしましたが、違いはありませんでした。これは私のコードで行っている唯一のスキャン操作です。

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

答えて

1

@YosukeMatsudaのヒントのおかげで、LastEvaluatedKeyが空になるまでScanを繰り返し呼び出すことでこれを解決できました。残念ながら、マイクの答えが正しい問題を指摘しておらず、誤解を招くため、私はこれを回答として掲示しています。

は、ここで私は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バージョンを使用しています。 ObjectiveCであなたはより近代的なフィルタ式 APIを使用している間、あなたは古いフィルタ条件 APIを使用しているAndroidのバージョンで

  1. 。これは必ずしも新規の方が失敗がありませんが、それだけでExpressionAttributeValuesの場合に
  2. を指摘するものだ、あなたが渡しているlocationeventの値はタイプAWSDynamoDBAttributeValue *、ない文字列でなければなりません。この変更を行うと、クエリが動作する可能性が高くなります。

私はこれがあなたの質問に答える願っていますが、あなただけを言うので、特定することはできません「のAndroidに期待通り、この作品 - どのように私はそれがiOS版で動作させることができます」ができますが、壊れているものを告げていません。

+0

私が言及したように:「このスキャンは、提供されたエントリに対して結果を受け取るべきであることを検証したにもかかわらず、ゼロ結果を返す」はい、Androidはサポートしていますが、古いフィルタ条件を使用していますが、iOSはサポートしていません。 – LNI

+0

'location'と' event'をインスタンス化する方法を提供する必要があります。また、[冗長なログを有効にする](http://docs.aws.amazon.com/mobile/sdkforios/developerguide/setup.html)を参照して、リクエストJSONで質問を更新してください。 –

+0

verbose loggingオプションの出力で質問を更新しました。イベントと場所の両方が文字列です。上記の出力は、それらが正しく設定されていることを示しています。 DynamoDBコンソールを使用してクエリ内のイベントと場所に同じ値を使用すると、スキャンによって値が正常に返されます。 – LNI

関連する問題