Node.js 仅 AWS DynamoDB 扫描特定字段
Node.js AWS DynamoDB Scan specific field(s) only
在许多AWS DynamoDB
数据中,我想使用node.js
搜索特定的键值数据。
我的数据库单键示例如下。
{
"device_id" : "abcde12345", // Primary Key, String
"setting": {
"left_motor": 30,
"right_motor": 30,
"motor_name": "STRING_WHAT_I_WANT_TO_CHECK"
},
"another_fields1" : "1234",
"another_fields2": {
"key1" : 1,
"key2" : "2",
"key3" : { ... }
}
}
我收集所有物品的代码 motor_name 如下所示。
// require modules
var fs = require('fs'); // used for save json-result.
var AWS = require('aws-sdk');
var config = require('./config_file'); // secret data
var schedule = require('node-schedule');
AWS.config.update({
region: config.dynamodb.region,
endpoint: config.dynamodb.endpoint,
accessKeyId: config.dynamodb.access_key,
secretAccessKey: config.dynamodb.secret_key
});
var documentClient = new AWS.DynamoDB.DocumentClient();
var params = {
TableName: config.dynamodb.device_table
};
// I set run once at 9 o'clock, but after do single-time, I kill pm2 process.
// (just for run once only)
var motor_name_list = {}; // result will be saved.
var j = schedule.scheduleJob("0 0 9 * * *", function() {
documentClient.scan(params, onScan);
});
function onScan(err, data) {
if(err) {
console.log(err);
}
else { // READ SUCCESS
/*
'single_item' sample is like upper json-code
But, I reference only one value, setting.motor_name
*/
data.Items.forEach(function(single_item) {
// process scan success datas
var motor_name = single_item.setting.motor_name;
if(motor_name_list.hasOwnProperty(motor_name))
motor_name_list[motor_name] += 1;
else
motor_name_list[motor_name] = 1;
});
if(typeof data.LastEvaluatedKey != 'undefined') {
params.ExclusiveStartKey = data.LastEvaluatedKey;
// Because of Read Limit per minute, I delay next-step for one minute.
// (maybe, ReadCapacityUnits)
setTimeout(function() {
documentClient.scan(params, onScan);
}, 60 * 1000);
}
else {
// save motor_name_list as a file (fs.writeFileSync...)
}
} // END OF READ SUCCESS
}
由于延迟,所以需要很多时间。 (实际上是 10~15 分钟)。
(单个onScan
读了300~500条,我有将近5000条。
有什么方法可以在不改变我的 json 格式的情况下只扫描单个项目吗?
感谢您阅读我的问题。
有什么方法可以在不改变我的 json 格式的情况下只扫描单个项目吗?
很遗憾没有,您必须使用Scan
来搜索非关键属性
假设无法更改 schema
,但您可以添加一个额外的 attribute
并且您愿意 接受一些重复:
- 将
motor_name
的副本另存为 setting_motor_name
作为顶级属性
- 在
setting_motor_name
上创建 GSI
- 在
setting_motor_name
上使用Query
实现毫秒级效率
一目了然:
{
"setting": {
"left_motor": 30,
"right_motor": 30,
"motor_name": "STRING_WHAT_I_WANT_TO_CHECK"
},
"setting_motor_name": "STRING_WHAT_I_WANT_TO_CHECK"
}
权衡是:
- 您必须注意为您保留的任何现有数据插入
setting_motor_name
- 对
setting.motor_name
的任何更新都应更新为 setting_motor_name
--
最好的方案是保持此数据平坦,但这需要侵入性地更改架构。这样就没有重复,你可以在 motor_name
上应用 GSI
因为它是顶级属性
{
"setting": {
"left_motor": 30,
"right_motor": 30
},
"motor_name": "STRING_WHAT_I_WANT_TO_CHECK"
}
在许多AWS DynamoDB
数据中,我想使用node.js
搜索特定的键值数据。
我的数据库单键示例如下。
{
"device_id" : "abcde12345", // Primary Key, String
"setting": {
"left_motor": 30,
"right_motor": 30,
"motor_name": "STRING_WHAT_I_WANT_TO_CHECK"
},
"another_fields1" : "1234",
"another_fields2": {
"key1" : 1,
"key2" : "2",
"key3" : { ... }
}
}
我收集所有物品的代码 motor_name 如下所示。
// require modules
var fs = require('fs'); // used for save json-result.
var AWS = require('aws-sdk');
var config = require('./config_file'); // secret data
var schedule = require('node-schedule');
AWS.config.update({
region: config.dynamodb.region,
endpoint: config.dynamodb.endpoint,
accessKeyId: config.dynamodb.access_key,
secretAccessKey: config.dynamodb.secret_key
});
var documentClient = new AWS.DynamoDB.DocumentClient();
var params = {
TableName: config.dynamodb.device_table
};
// I set run once at 9 o'clock, but after do single-time, I kill pm2 process.
// (just for run once only)
var motor_name_list = {}; // result will be saved.
var j = schedule.scheduleJob("0 0 9 * * *", function() {
documentClient.scan(params, onScan);
});
function onScan(err, data) {
if(err) {
console.log(err);
}
else { // READ SUCCESS
/*
'single_item' sample is like upper json-code
But, I reference only one value, setting.motor_name
*/
data.Items.forEach(function(single_item) {
// process scan success datas
var motor_name = single_item.setting.motor_name;
if(motor_name_list.hasOwnProperty(motor_name))
motor_name_list[motor_name] += 1;
else
motor_name_list[motor_name] = 1;
});
if(typeof data.LastEvaluatedKey != 'undefined') {
params.ExclusiveStartKey = data.LastEvaluatedKey;
// Because of Read Limit per minute, I delay next-step for one minute.
// (maybe, ReadCapacityUnits)
setTimeout(function() {
documentClient.scan(params, onScan);
}, 60 * 1000);
}
else {
// save motor_name_list as a file (fs.writeFileSync...)
}
} // END OF READ SUCCESS
}
由于延迟,所以需要很多时间。 (实际上是 10~15 分钟)。
(单个onScan
读了300~500条,我有将近5000条。
有什么方法可以在不改变我的 json 格式的情况下只扫描单个项目吗?
感谢您阅读我的问题。
有什么方法可以在不改变我的 json 格式的情况下只扫描单个项目吗?
很遗憾没有,您必须使用Scan
来搜索非关键属性
假设无法更改 schema
,但您可以添加一个额外的 attribute
并且您愿意 接受一些重复:
- 将
motor_name
的副本另存为setting_motor_name
作为顶级属性 - 在
setting_motor_name
上创建 - 在
setting_motor_name
上使用Query
实现毫秒级效率
GSI
一目了然:
{
"setting": {
"left_motor": 30,
"right_motor": 30,
"motor_name": "STRING_WHAT_I_WANT_TO_CHECK"
},
"setting_motor_name": "STRING_WHAT_I_WANT_TO_CHECK"
}
权衡是:
- 您必须注意为您保留的任何现有数据插入
setting_motor_name
- 对
setting.motor_name
的任何更新都应更新为setting_motor_name
--
最好的方案是保持此数据平坦,但这需要侵入性地更改架构。这样就没有重复,你可以在 motor_name
上应用 GSI
因为它是顶级属性
{
"setting": {
"left_motor": 30,
"right_motor": 30
},
"motor_name": "STRING_WHAT_I_WANT_TO_CHECK"
}