我正在尝试编写一个查询AWS DynamoDB商店的GraphQL服务器。
出于这个问题的目的,GraphQL部分是无关紧要的,除了参数的形式如下:
{
key1: value1,
key2: value2,
key3: value3
}
这些键/值对用于查询数据库。只有严格的平等,没什么特别的。所有参数都是可选的。
这是我想出的:
import { DynamoDB } from 'aws-sdk';
function constructParams(tableName, fields = {}) {
const keys = Object.keys(fields);
if (keys.length === 0) {
return {
TableName: tableName,
};
}
const filters = keys.map(key => `#${key} = :${key}`);
const attributeNames = keys.reduce((memo, key) => Object.assign(memo, {
[`#${key}`]: key,
}), {});
const attributeValues = keys.reduce((memo, key) => Object.assign(memo, {
[`:${key}`]: fields[key],
}), {});
return {
TableName: tableName,
FilterExpression: filters.join(' AND '),
ExpressionAttributeNames: attributeNames,
ExpressionAttributeValues: attributeValues,
};
}
function query(tableName, fields = {}) {
const docClient = new DynamoDB.DocumentClient({ region: 'ap-southeast-2' });
const params = constructParams(tableName, fields);
return new Promise((resolve, reject) => {
docClient.scan(params, (err, data) => {
if (err) {
reject(err);
} else {
resolve(data.Items);
}
});
});
}
export default query;
这很好用。但是,它很麻烦。我的constructParams
功能感觉就像是不必要的样板。 MongoDB完全没有这样的功能。
这样说,为什么我觉得我在为NoSQL数据库编写SQL?
答案 0 :(得分:1)
您所写的内容确实是您尝试实现的最短代码,因为DynamoDB希望过滤Scan
的信息。
如果它有助于降低代码复杂性,您还可以考虑将过滤从DynamoDB端迁移到客户端。这不会改变消耗的读取容量单位,因此您的读取成本将保持不变。
答案 1 :(得分:0)
可悲的是,我尝试使用DynamoDB实现的目标是不可能的。
scan
方法表面上提供此功能。但它实际上只返回整个表集,然后过滤。一旦您的数据集达到一定的大小,scan
就会停止工作。
query
方法是您真正应该使用的方法。但它不允许对两个以上的密钥进行查询。这简直令人震惊。对于所谓的数据库来说,这是非常不足的。
换句话说,DynamoDB API并不仅仅是语法原语。它在功能上也是原始的。