我需要通过与其主键不同的密钥来查询DynamoDB表。我试图为它创建一个全球二级索引。但是我收到此错误:“查询关键条件不支持dynamodb”。通过查看一些示例,看起来我不能通过二级索引查询,除非我还包括主索引/键,这是正确的吗?假设我需要查询在某个城市工作的所有员工,我可以在没有employeeID的情况下进行查询吗?
更新信息 也许我的索引不是应该创建的?
表格信息:
GSI:
当我从节点I查询作为参数发送的城市和索引名称:
const filter = { city: city};
return this.getRecordsFromDb(filter, { IndexName: "myIndexName" })
.then(records => __.head(records));
答案 0 :(得分:14)
注意: - 由于您尚未提供完整代码,因此很难模拟和识别问题。但是,我创建了类似的表和索引。这对我来说可以。您可以参考以下代码了解更多详情。
这是表创建脚本并查询索引。
如果需要,您可以更改表名和索引名。我遵循了你在帖子中提到的相同的键属性结构。
这已经过测试并且运行正常。
1)创建表格' city'使用索引' city_index':
var params = {
TableName: 'city',
KeySchema: [ // The type of of schema. Must start with a HASH type, with an optional second RANGE.
{ // Required HASH type attribute
AttributeName: 'id',
KeyType: 'HASH',
},
{ // Required HASH type attribute
AttributeName: 'name',
KeyType: 'RANGE',
}
],
AttributeDefinitions: [ // The names and types of all primary and index key attributes only
{
AttributeName: 'id',
AttributeType: 'S', // (S | N | B) for string, number, binary
},
{
AttributeName: 'name',
AttributeType: 'S', // (S | N | B) for string, number, binary
},
{
AttributeName: 'city',
AttributeType: 'S', // (S | N | B) for string, number, binary
},
],
ProvisionedThroughput: { // required provisioned throughput for the table
ReadCapacityUnits: 400,
WriteCapacityUnits: 400,
},
GlobalSecondaryIndexes: [ // optional (list of GlobalSecondaryIndex)
{
IndexName: 'city_index',
KeySchema: [
{ // Required HASH type attribute
AttributeName: 'city',
KeyType: 'HASH',
}
],
Projection: { // attributes to project into the index
ProjectionType: 'ALL' // (ALL | KEYS_ONLY | INCLUDE)
},
ProvisionedThroughput: { // throughput to provision to the index
ReadCapacityUnits: 400,
WriteCapacityUnits: 400,
},
},
// ... more global secondary indexes ...
],
};
dynamodb.createTable(params, function(err, data) {
if (err){ console.log("error :" +JSON.stringify(err));} // an error occurred
else console.log("success :" +JSON.stringify(data)); // successful response
});
2)将一些数据插入城市表
3)使用索引查询: -
var docClient = new AWS.DynamoDB.DocumentClient();
var table = "city";
var params = {
TableName : table,
IndexName : 'city_index',
KeyConditionExpression : 'city = :cityVal',
ExpressionAttributeValues : {
':cityVal' : 'london'
}
};
docClient.query(params, function(err, data) {
if (err) {
console.error("Unable to read item. Error JSON:", JSON.stringify(err,
null, 2));
} else {
console.log("GetItem succeeded:", JSON.stringify(data, null, 2));
}
});
答案 1 :(得分:0)
这是我用scan使用Node.js(由另一个字段查询)的实现:
var params = {
TableName: 'TableName',
FilterExpression: 'AnotherFieldName = :email',
ExpressionAttributeValues: {
":email": { S: emailISearchFor }
}
};
ddb.scan(params, function(err, data){
if(err){
...
} else {
if(data.Items.length > 0){ // here is the info
valueIWant = data.Items[0].PrimaryKeyName.S;
}
}
});