我正在尝试使用以下代码查询2017-12-06 19:18:13.891 WARN 11252 --- [uits-Executor-1] i.g.j.c.liquibase.AsyncSpringLiquibase : Starting Liquibase asynchronously, your database might not be ready at startup!
2017-12-06 19:18:34.044 DEBUG 11252 --- [ restartedMain] i.g.j.c.apidoc.SwaggerConfiguration : Starting Swagger
2017-12-06 19:18:34.055 DEBUG 11252 --- [ restartedMain] i.g.j.c.apidoc.SwaggerConfiguration : Started Swagger in 8 ms
2017-12-06 19:18:41.574 INFO 11252 --- [ restartedMain] com.akton.test.DemoApp : Started DemoApp in 51.121 seconds (JVM running for 51.852)
2017-12-06 19:18:46.161 DEBUG 11252 --- [uits-Executor-1] i.g.j.c.liquibase.AsyncSpringLiquibase : Liquibase has updated your database in 32269 ms
2017-12-06 19:18:46.161 WARN 11252 --- [uits-Executor-1] i.g.j.c.liquibase.AsyncSpringLiquibase : Warning, Liquibase took more than 5 seconds to start up!
:
dynamodb
当我运行时,我收到一条错误消息:
const AWS = require('aws-sdk');
let dynamo = new AWS.DynamoDB.DocumentClient({
service: new AWS.DynamoDB(
{
apiVersion: "2012-08-10",
region: "us-east-1"
}),
convertEmptyValues: true
});
dynamo.query({
TableName: "Jobs",
KeyConditionExpression: 'sstatus = :st',
ExpressionAttributeValues: {
':st': 'processing'
}
}, (err, resp) => {
console.log(err, resp);
});
我不明白这一点。我已将ValidationException: Query condition missed key schema element: id
定义为id
表的分区键,需要查找jobs
状态的所有作业。
答案 0 :(得分:23)
您尝试使用不包含主键的条件运行查询。这是how queries work in DynamoDB。您需要执行scan for the info in your case,但是,我认为这不是最好的选择。
我认为您要设置global secondary index并使用它来查询processing
状态。
答案 1 :(得分:2)
在另一个答案中,@ smcstewart回答了这个问题。但是他提供了一个链接,而不是评论为什么会发生此错误。我想添加一个简短的评论,希望可以节省您的时间。
AWS dox on Querying a Table指出,您可以DynamoDB方式进行WHERE条件查询(例如SQL查询SELECT * FROM Music WHERE Artist ='Noone You Know';),但要注意一个重要警告:
“您必须为PARTITION键指定一个EQUALITY条件,并且可以选择为SORT键提供另一个条件。” (这意味着您只能将关键属性与Query一起使用。以其他任何方式进行操作都意味着DynamoDB会为您运行完整扫描,但效率不高-比使用全局二级索引效率低。)
因此,如果您需要使用Query来查询非关键属性,通常不是一个选择-最佳选择是使用Global Secondary Indexes,如@smcstewart所建议。
我发现this guide对于手动创建全局二级索引很有用。
如果您需要使用CloudFormation here is a relevant page添加它。
答案 2 :(得分:0)
我在其他情况下遇到此错误。这是我的情况。 (其他人以这种情况结束的可能性很小,但以防万一)
我在一个表上工作(例如表A)。表A具有分区键m_id和排序键u_id。 我有一个查询以使用m_id提取数据。该查询正在运行。
'''
var queryParams = {
ExpressionAttributeValues: {
':m_id': mId
},
KeyConditionExpression: 'm_id = :m_id',
TableName: "A"
};
let connections = await docClient.query(queryParams).promise();
'''
我创建了另一个表TableB。在命名键时发生了一些错误,因此我只是删除并再次创建了一个具有相同名称的表TableB。表B具有分区键m_id和排序键s_id。
我复制并粘贴了与表A相同的查询,只是因为分区键具有相同的名称,所以更改了表名。
令我震惊的是,我得到了这种期望。
“ ValidationException:查询条件缺少键架构元素”
我重新检查了所有名称,将查询与工作查询进行了比较。一切都很好。 我想也许是因为,我正在删除重新创建表B,可能与此有关。因此,我用新名称表B2创建了一个新表,该表具有与表B相同的键名。
在引发异常的查询中,我仅将表名称从B更改为B2。 而且异常消失了。
如果您是在一个新的表上获得此表(以前没有查询曾在其中工作过),则可以选择使用新名称创建一个新表。
如果您仅删除表以更改分区键名称,那么为表使用新名称可能更安全(Dynamo可能通过表名而不是内部标识符来引用元数据,即使您删除表格,旧的元数据也可能会保留。考虑到我遇到的这种情况,这只是一个猜测。
答案 3 :(得分:0)
您必须为状态字段创建全局二级索引。 然后,您的代码可能看起来像这样:
dynamo.query({
TableName: "Jobs",
IndexName: 'status',
KeyConditionExpression: '#s = :st',
ExpressionAttributeValues: {
':st': 'processing'
},
ExpressionAttributeNames: {
'#s': 'status',
},
}, (err, resp) => {
console.log(err, resp);
});
注意:扫描操作的成本确实很高,尤其是当你的表很大时
答案 4 :(得分:-1)
我使用带扫描的AWS.DynamoDB.DocumentClient()解决了示例(nodejs)的问题:
var docClient = new AWS.DynamoDB.DocumentClient();
var params = {
TableName: "product",
FilterExpression: "#cg = :data",
ExpressionAttributeNames: {
"#cg": "categoria",
},
ExpressionAttributeValues: {
":data": category,
}
};
docClient.scan(params, onScan);
function onScan(err, data) {
if (err) {
// for the log in server
console.error("Unable to scan the table. Error JSON:", JSON.stringify(err, null, 2));
res.json(err);
} else {
console.log("Scan succeeded.");
res.json(data);
}
}