如何在 DynamoDB 中查询不存在的(空)属性
Posted
技术标签:
【中文标题】如何在 DynamoDB 中查询不存在的(空)属性【英文标题】:How do you query for a non-existent (null) attribute in DynamoDB 【发布时间】:2016-03-24 18:43:16 【问题描述】:我正在尝试查询 DynamoDB 表以查找未设置 email
属性的所有项目。名为EmailPasswordIndex
的全局二级索引存在于包含email
字段的表中。
var params =
"TableName": "Accounts",
"IndexName": "EmailPasswordIndex",
"KeyConditionExpression": "email = NULL",
;
dynamodb.query(params, function(err, data)
if (err)
console.log(JSON.stringify(err, null, 2));
else
console.log(JSON.stringify(data, null, 2));
);
结果:
"message": "Invalid KeyConditionExpression: Attribute name is a reserved keyword; reserved keyword: NULL",
"code": "ValidationException",
"time": "2015-12-18T05:33:00.356Z",
"statusCode": 400,
"retryable": false
表定义:
var params =
"TableName": "Accounts",
"KeySchema": [
"AttributeName": "id", KeyType: "HASH" , // Randomly generated UUID
],
"AttributeDefinitions": [
"AttributeName": "id", AttributeType: "S" ,
"AttributeName": "email", AttributeType: "S" , // User e-mail.
"AttributeName": "password", AttributeType: "S" , // Hashed password.
],
"GlobalSecondaryIndexes": [
"IndexName": "EmailPasswordIndex",
"ProvisionedThroughput":
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1
,
"KeySchema": [
"AttributeName": "email", KeyType: "HASH" ,
"AttributeName": "password", KeyType: "RANGE" ,
],
"Projection": "ProjectionType": "ALL"
,
],
ProvisionedThroughput:
ReadCapacityUnits: 1,
WriteCapacityUnits: 1
;
dynamodb.createTable(params, function(err, data)
if (err)
console.log(JSON.stringify(err, null, 2));
else
console.log(JSON.stringify(data, null, 2));
);
【问题讨论】:
你能提供你的表和索引属性定义吗? @mkobit 已添加,谢谢。 【参考方案1】:既然 DynamoDB 就是这样,就需要使用非正统的方法来使用数据库。
我只是引入了一个特殊值,它可以是您的域中可以安全识别的任何内容(例如 "--NULL--"
),然后在最低数据层将其与 null
进行转换。
查询该字段为 null 的条目只是查询该特殊值。
从习惯 SQL 的人的角度来看,这不是很好,但比扫描更好。
对于旧条目,您将需要一次性迁移。
【讨论】:
【参考方案2】:@jaredHatfield 如果该字段不存在则正确,但如果该字段为空,则该字段将不起作用。 NULL 是关键字,不能直接使用。但是您可以将它与 ExpressionAttributeValues 一起使用。
const params =
TableName: "Accounts",
FilterExpression: "attribute_not_exists(email) or email = :null",
ExpressionAttributeValues:
':null': null
dynamodb.scan(params, (err, data) =>
if (err)
console.log(JSON.stringify(err, null, 2));
else
console.log(JSON.stringify(data, null, 2));
)
【讨论】:
谢谢你的精确度,我就是在找那个:)【参考方案3】:DynamoDB 的全局二级索引允许索引稀疏。这意味着,如果您有一个 GSI,其项目的哈希或范围键未定义,则该项目将根本不包含在 GSI 中。这在许多用例中都很有用,因为它允许您直接识别包含某些字段的记录。但是,如果您正在寻找缺少字段,则此方法将不起作用。
要获取所有未设置字段的项目,您最好的选择可能是使用过滤器进行扫描。此操作将非常昂贵,但它会是如下所示的简单代码:
var params =
TableName: "Accounts",
FilterExpression: "attribute_not_exists(email)"
;
dynamodb.scan(params,
if (err)
console.log(JSON.stringify(err, null, 2));
else
console.log(JSON.stringify(data, null, 2));
);
【讨论】:
以上是关于如何在 DynamoDB 中查询不存在的(空)属性的主要内容,如果未能解决你的问题,请参考以下文章
可以将HASH密钥更新为预先存在的Dynamodb全局二级索引的另一个属性吗?