node.js - Node.js AWS DynamoDB 仅扫描特定字段
问题描述
在许多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
顶级属性 - 创建
GSI
一个setting_motor_name
- 使用
Query
onsetting_motor_name
实现毫秒级效率
乍看上去:
{
"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
--
最好的方案是保持这些数据平坦,但这需要侵入性地更改模式。这样就没有重复了,你可以申请GSI
,motor_name
因为它是顶级属性
{
"setting": {
"left_motor": 30,
"right_motor": 30
},
"motor_name": "STRING_WHAT_I_WANT_TO_CHECK"
}
推荐阅读
- ruby - 每种方法中的厨师通知
- c - 嵌入式内存分配和范围
- android - Kotlin - 将地图结果转换为类型化的数组列表
- html - 当 div 有宽度时,如何使用 flexbox 使元素居中?
- mongodb - 当回调函数用于猫鼬时,第二个参数继承了什么?
- python - 如何在python中按字母顺序打印两列
- java - java中代码和消息的异常处理
- javascript - 如果条件为真,检查验证脚本不返回
- asp.net-core - 使用 GraphQL API 的清洁架构 CQRS
- node.js - 如何从数组中读取特定元素,该元素是来自 mongodb 的车把文件中对象的一部分?