2015-09-19 30 views
2

声明我有一个“用户”表,这里是一个示例:“IN”在dynamodb

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

我的愿望是检索其formattedPhoneNumber包含在电话号码阵列中的所有用户(从检索到的我联系人)。我创建了一个辅助索引,验证为HASH并将格式化的PhoneNumber格式化为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\"",

是不是有什么毛病IN关键字? 也许有另一种方法来实现这一目标?

+0

你试过“(verified =:v)AND(formattedPhone 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

嗯好的,谢谢!这意味着它会从数据库获取所有项目,然后过滤它的权利? –

+0

是的 - 所以请保持KeyConditionExpression验证= 1,但为格式化的PhoneNumber IN []添加过滤器表达式。这样,请求只会获取验证= 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; 
}