我应该使用扫描还是查询?
Should I use scan or query?
我在 DynamoDB 中很难选择两个日期之间的一组条目。我的日期是字符串,格式简单为“2018-01-01”。
我应该使用查询还是扫描?我的参数看起来还好吗?该操作似乎有效,但我没有得到任何结果。我做错了什么?
这是我的代码:
// get transactions for {month} and {year}
api.get('/transaction/tab/{year}/{month}', (request) => {
const year = request.pathParams.year
const month = request.pathParams.month
const params = {
TableName: request.env.tableName,
KeyConditionExpression: '#date between :val1 and :val2',
ExpressionAttributeNames: {
'#date': 'date'
},
ExpressionAttributeValues: {
':val1': {
S: year +'-' + month + '-01'
},
':val2': {
S: year + '-' + month + '-' + getDaysInMonth(month, year)
}
}
}
console.log(params)
// post-process dynamo result before returning
dynamoDb.query(params, (err, data) => {
console.log(data)
if (err) {
console.error('Unable to query. Error:', JSON.stringify(err, null, 2))
return 'Unable to query. Error: '+ JSON.stringify(err, null, 2)
} else {
console.log('Query succeeded.')
data.Items.forEach((item) => {
console.log(' -', item.year + ': ' + item.title)
})
return data.Items
}
})
})
DynamoDB 本身不支持 date/time
类型。所以我建议将日期存储为 UTC Number
,又名 Unix epoch time
并使用 Query
,因为它比 Scan
好得多
快速查看以下文章以了解如何转换为 unix 时间戳:
https://coderwall.com/p/rbfl6g/how-to-get-the-correct-unix-timestamp-from-any-date-in-javascript
当您使用 KeyConditionExpression
表达式时,这意味着您在 GSI
.
上使用了 Query
如果 date
是分区键而不是排序键。那么,你有问题了:
您没有在参数中定义 IndexName
。
在查询操作中,您不能对分区键执行比较测试(<、>、BETWEEN、...)。该条件必须对单个分区键值执行相等性测试 (=),并且可以选择对单个排序键值执行多个比较测试之一。
例如:
KeyConditionExpression: 'HashKey = :hkey and RangeKey > :rkey'
你想要 transactions
一个月吗?我认为,您必须使用以下内容创建 GSI:year-month
是 PrimaryKey(例如:2018-01、2018-02),day-createdAt
是 SortedKey(例如:28-1535429111358,...)
查询将如上:
const params = {
TableName: request.env.tableName,
IndexName: 'MONTH-DAY-IDX',
KeyConditionExpression: 'year-month = :val1',
ExpressionAttributeValues: {
':val1': {
S: year +'-' + month
},
}
}
我在 DynamoDB 中很难选择两个日期之间的一组条目。我的日期是字符串,格式简单为“2018-01-01”。
我应该使用查询还是扫描?我的参数看起来还好吗?该操作似乎有效,但我没有得到任何结果。我做错了什么?
这是我的代码:
// get transactions for {month} and {year}
api.get('/transaction/tab/{year}/{month}', (request) => {
const year = request.pathParams.year
const month = request.pathParams.month
const params = {
TableName: request.env.tableName,
KeyConditionExpression: '#date between :val1 and :val2',
ExpressionAttributeNames: {
'#date': 'date'
},
ExpressionAttributeValues: {
':val1': {
S: year +'-' + month + '-01'
},
':val2': {
S: year + '-' + month + '-' + getDaysInMonth(month, year)
}
}
}
console.log(params)
// post-process dynamo result before returning
dynamoDb.query(params, (err, data) => {
console.log(data)
if (err) {
console.error('Unable to query. Error:', JSON.stringify(err, null, 2))
return 'Unable to query. Error: '+ JSON.stringify(err, null, 2)
} else {
console.log('Query succeeded.')
data.Items.forEach((item) => {
console.log(' -', item.year + ': ' + item.title)
})
return data.Items
}
})
})
DynamoDB 本身不支持 date/time
类型。所以我建议将日期存储为 UTC Number
,又名 Unix epoch time
并使用 Query
,因为它比 Scan
快速查看以下文章以了解如何转换为 unix 时间戳:
https://coderwall.com/p/rbfl6g/how-to-get-the-correct-unix-timestamp-from-any-date-in-javascript
当您使用 KeyConditionExpression
表达式时,这意味着您在 GSI
.
Query
如果 date
是分区键而不是排序键。那么,你有问题了:
您没有在参数中定义 IndexName
。
在查询操作中,您不能对分区键执行比较测试(<、>、BETWEEN、...)。该条件必须对单个分区键值执行相等性测试 (=),并且可以选择对单个排序键值执行多个比较测试之一。
例如:
KeyConditionExpression: 'HashKey = :hkey and RangeKey > :rkey'
你想要 transactions
一个月吗?我认为,您必须使用以下内容创建 GSI:year-month
是 PrimaryKey(例如:2018-01、2018-02),day-createdAt
是 SortedKey(例如:28-1535429111358,...)
查询将如上:
const params = {
TableName: request.env.tableName,
IndexName: 'MONTH-DAY-IDX',
KeyConditionExpression: 'year-month = :val1',
ExpressionAttributeValues: {
':val1': {
S: year +'-' + month
},
}
}