web-dev-qa-db-ja.com

dynamodbの「IN」ステートメント

「ユーザー」テーブルがあります。ここにサンプルがあります:

{
    username:"haddox",
    formattedPhoneNumber:"676767676",
    verified: 0,
}

私の希望は、formattedPhoneNumberが電話番号の配列(連絡先から取得)に含まれているすべてのユーザーを取得することです。 HASHとして検証され、RANGEとしてフォーマットされたPhoneNumberを持つセカンダリインデックスを作成しました。これが私の試みです:

var params = {
    TableName: "Users",
    IndexName: "FormattedPhoneSecondaryIndex",
    KeyConditionExpression: "verified  = :v AND formattedPhone IN :n",
    ExpressionAttributeValues: {
        ":v":1,
        ":n": ["672053916", "642117296"]
    },
    ProjectionExpression: "username, formattedPhoneNumber"
};



dynamodb.query(params, function(err, data) {
    if (err)
        console.log(JSON.stringify(err, null, 2));
    else
        console.log(JSON.stringify(data, null, 2));
});

しかし、次のエラーが発生します:Invalid KeyConditionExpression: Syntax error; token: \":n\", near: \"IN :n\"",

INキーワードに問題がありますか?多分これを達成する別の方法がありますか?

KeyConditionExpressionは「IN」演算子を使用できません( http://docs.aws.Amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#FilteringResults を参照)。クエリ操作でKeyConditions/KeyConditionExpressionを使用するアイデアは、DynamoDBから項目のページをより効率的に読み取ることです。これは、ハッシュキーは同じで範囲キーが異なる項目が連続してソートされた順序で格納されるためです。 IN演算子は、特定のページの小さな部分を抽出する必要があるため、Query操作の効率が低下するため、KeyConditionsでは許可されていません。代わりに、これをFilterExpressionとして追加します。これは、DynamoDBから返される項目の数を減らすための便利なパラメーターですが、DynamoDBからのデータの読み取り方法には影響しません。

13
Jeffrey Nieh

これが私たちが解決した方法です。

-(AWSDynamoDBScanExpression *) prepareScanExpressionWithName:(NSString*)name andValues:(NSArray *)vals {

AWSDynamoDBScanExpression *scanExpression = [AWSDynamoDBScanExpression new];

NSMutableString* filterExpression = [NSMutableString string];

NSMutableDictionary* expression = [NSMutableDictionary dictionary];

for(int i = 0; i < vals.count; i++)
    NSString *val = vals[i];
    NSString* key = [NSString stringWithFormat:@":val%i",i];

    [filterExpression appendString:key];
    [expression setObject:val forKey:key];

    if (i < vals.count) {
        [filterExpression appendString:@","];
    }
}

scanExpression.filterExpression = [NSString stringWithFormat:@"#P IN (%@)", filterExpression];
scanExpression.expressionAttributeNames = @{@"#P": name};
scanExpression.expressionAttributeValues = expression;
return scanExpression;
}
0
Min Soe