2015-09-19 5 views
2

У меня есть «Пользователи» таблицы, вот пример:«В» заявлении в dynamodb

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

Мое желание, чтобы получить все пользователи, formattedPhoneNumber содержится в массиве телефонных номеров (извлеченных из моего контакты). Я создал вторичный индекс, который был проверен как HASH и formattedPhoneNumber как RANGE. Вот моя попытка:

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\"",

Есть ли что-то не так с ключевым словом? Возможно, есть еще один способ добиться этого?

+0

Вы попробовали «(проверено =: v) И (форматированоPhone IN (: n))»? – jarmod

+0

Привет! Я просто попытался, но это не сработало. –

+0

@HadrienPierreMazelier вы можете вставить вам рабочий пример –

ответ

4

KeyConditionExpression не может использовать оператор «IN» (см. http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#FilteringResults). Идея с KeyConditions/KeyConditionExpression в операции запроса состоит в том, чтобы более эффективно считывать страницы элементов из DynamoDB, поскольку элементы с одним и тем же ключом хэша, но с разными клавишами диапазона хранятся смежно и упорядоченно. Оператору IN потребуется извлечь небольшие части определенных страниц, что делает операцию запроса менее эффективной, поэтому она не допускается в KeyConditions. Вы хотели бы добавить это как FilterExpression вместо этого, что является удобным параметром для уменьшения количества элементов, возвращаемых из DynamoDB, но не влияет на то, как данные считываются из DynamoDB.

+0

Хм, спасибо, спасибо! Это означает, что он получит все предметы из db, а затем отфильтрует его правильно? –

+0

Да - поэтому держите выражение KeyConditionExpression на проверке = 1, но добавьте выражение фильтра для форматированногоPhoneNumber IN []. Таким образом, запрос будет извлекать только те элементы, где verified = 1, а затем выполнить фильтр. –

+3

'scanExpression.filterExpression = @" Id IN (: val) "; scanExpression.expressionAttributeValues ​​= @ {@ ": val": [idList componentsJoinedByString: @ ","]}; 'Это как использовать? Я попытался поставить массив без успеха, вот почему присоединение к массиву –

1

Так мы решили.

-(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; 
}