查询条件缺少关键架构元素:验证错误
Posted
技术标签:
【中文标题】查询条件缺少关键架构元素:验证错误【英文标题】:Query condition missed key schema element : Validation Error 【发布时间】:2018-05-20 17:40:59 【问题描述】:我正在尝试使用以下代码查询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
表的分区键,需要找到所有处于processing
状态的作业。
【问题讨论】:
【参考方案1】:您正在尝试使用不包含主键的条件运行查询。这是how queries work in DynamoDB。您需要发送scan for the info in your case,但是,我认为这不是最好的选择。
我认为您想设置一个global secondary index 并使用它来查询processing
状态。
【讨论】:
请您在chat.***.com/rooms/160644/…这里讨论这个问题 根据定义,查询与键查找不是已经针对 GSI 了吗?我在 GSI 上运行查询操作时遇到此错误... @anon58192932 在不知道具体情况的情况下,我的直觉告诉我您要过滤的字段不在您的 GSI 中。如果您有具体细节,那就更好了。 有几种方法可以解决此错误。我发现的两个是:1)使用已弃用的 api 代替 KeyConditionExpression 和 2)我的 GSI 定义中的错字。我希望 GSI 作为索引的值与索引的实际值之间存在不匹配。删除并重新定义索引修复了它。 仅仅这个问题和答案就让我远离了这个数据库。【参考方案2】:在另一个答案中 @smcstewart 回答了这个问题。但是他提供了一个链接,而不是评论为什么会发生这个错误。我想添加一个简短的评论,希望它能节省您的时间。
AWS docs on Querying a Table 表示您可以使用 DynamoDB 方式进行WHERE
条件查询(例如SQL query SELECT * FROM Music WHERE Artist='No One You Know'
),但有一个重要警告:
您必须为 PARTITION 键指定一个 EQUALITY 条件,并且您可以选择为 SORT 键提供另一个条件。
意思是你只能使用Query
的关键属性。以任何其他方式执行此操作将意味着 DynamoDB 将为您运行 完全扫描,这效率不高 - 效率低于使用全局二级索引。
因此,如果您需要使用 Query 查询非关键属性,通常不是一种选择 - 最好的选择是按照 @smcstewart 的建议使用 Global Secondary Indexes。
我发现this guide 对手动创建全局二级索引很有用。
如果您需要使用 CloudFormation here is a relevant page 添加它。
【讨论】:
【参考方案3】:我使用 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);
【讨论】:
这不是一个可取的解决方案。扫描操作非常昂贵! 是的,重建你的表,添加一些索引并进行查询【参考方案4】:我在不同的情况下收到此错误。这是我的场景。 (其他人不太可能以这种情况告终,但以防万一)
我有一个查询表(比如表 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();
'''
我创建了另一个表,比如说表 B。我在命名键时犯了一些错误,所以我只是删除并再次创建了一个具有相同名称的表,表 B。表 B 具有分区键 m_id 和排序键 s_id。
我复制粘贴了用于表 A 的相同查询,我更改表名只是因为分区键具有相同的名称。
令我震惊的是,我得到了这样的期望。
“ValidationException:查询条件缺少关键架构元素”
我重新检查了所有名称,并将查询与工作查询进行了比较。一切都很好。 我想可能是因为,我正在删除重新创建表 B,这可能与此有关。因此,我创建了一个新表,其名称表 B2 与表 B 具有相同的键名。
在引发异常的查询中,我仅将表名称从 B 更改为 B2。 异常消失了。
如果您在新表上获取此信息,而之前没有任何查询有效,则可以选择创建一个具有新名称的新表。
如果您删除表只是为了更改分区键名称,那么为表使用新名称可能会更安全(Dynamo 可以通过表名而不是内部标识符来引用元数据,即使您删除了一个表,旧的元数据也可能会保留下来。鉴于我遇到了这种情况,这只是一个猜测)。
【讨论】:
【参考方案5】:您必须为状态字段创建一个全局二级索引。 然后,您的代码可能看起来像这样:
dynamo.query(
TableName: "Jobs",
IndexName: 'status',
KeyConditionExpression: '#s = :st',
ExpressionAttributeValues:
':st': 'processing'
,
ExpressionAttributeNames:
'#s': 'status',
,
, (err, resp) =>
console.log(err, resp);
);
注意:扫描操作确实非常昂贵,尤其是如果您的表很大时
【讨论】:
以上是关于查询条件缺少关键架构元素:验证错误的主要内容,如果未能解决你的问题,请参考以下文章
用于查询 dynamodb 的 boto3 资源:查询条件缺少关键架构元素
Oracle SQL - 使用 Case 语句缺少关键字错误的更新查询
当我尝试通过架构使用 DocumentBuilderFactory 验证 xml 文件时,我收到错误“找不到元素的声明”