2017-02-05 66 views
0

我正在尝试编写查询AWS DynamoDB商店的GraphQL服务器。查询DynamoDB的最佳方法

对于这个问题的目的,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

不幸的是,我想要达到的仅仅是DynamoDB无法实现的。

scan方法表面上提供了此功能。但它真的只是返回整个表集,然后过滤。一旦你的数据集达到一定的大小,scan停止工作。

query方法是你真正应该使用的。但它不允许在两个以上的键上进行查询。这简直令人震惊。对于一个所谓的数据库来说,这是极其不足的。

换句话说,DynamoDB API不仅仅是语法上的原始语言。它在功能上也是原始的。

1

你写的是你试图实现的最短代码,因为DynamoDB期望为Scan过滤信息。

如果有助于降低代码复杂性,您还可以考虑将过滤从DynamoDB端移动到客户端。这不会改变所消耗的读取容量单位,所以您的读取成本将保持不变。