在nodejs中使用FilterExpression进行DynamoDB扫描

时间:2018-03-15 03:27:17

标签: node.js aws-lambda amazon-dynamodb

我正在尝试从DynamoDB表中检索与FilterExpression匹配的所有项目,虽然扫描了所有项目但一半匹配,但不会返回预期的项目。

我在Node.js 6.10上运行的AWS Lambda函数中有以下内容:

var AWS = require("aws-sdk"),
    documentClient = new AWS.DynamoDB.DocumentClient();
function fetchQuotes(category) {
    let params = {
        "TableName": "quotient-quotes",
        "FilterExpression": "category = :cat",
        "ExpressionAttributeValues": {":cat": {"S": category}}
    };
    console.log(`params=${JSON.stringify(params)}`);
    documentClient.scan(params, function(err, data) {
        if (err) {
            console.error(JSON.stringify(err));
        } else {
            console.log(JSON.stringify(data));
        }
    });
}

表格中有10个项目,其中一个是:

{
  "category": "ChuckNorris",
  "quote": "Chuck Norris does not sleep. He waits.",
  "uuid": "844a0af7-71e9-41b0-9ca7-d090bb71fdb8"
}

使用“ChuckNorris”类别进行测试时,日志显示:

params={"TableName":"quotient-quotes","FilterExpression":"category = :cat","ExpressionAttributeValues":{":cat":{"S":"ChuckNorris"}}}
{"Items":[],"Count":0,"ScannedCount":10}

当我只指定scan时,TableName调用会返回所有10个项目:

params={"TableName":"quotient-quotes"}
{"Items":[<snip>,{"category":"ChuckNorris","uuid":"844a0af7-71e9-41b0-9ca7-d090bb71fdb8","CamelCase":"thevalue","quote":"Chuck Norris does not sleep. He waits."},<snip>],"Count":10,"ScannedCount":10}

2 个答案:

答案 0 :(得分:6)

您不需要在"S"中指定类型(ExpressionAttributeValues),因为您使用的是DynamoDB DocumentClient。根据{{​​3}}:

  

文档客户端通过抽象出属性值的概念,简化了在Amazon DynamoDB中处理项目的过程。此抽象注释作为输入参数提供的本机JavaScript类型,以及将带注释的响应数据转换为本机JavaScript类型。

只有当您通过new AWS.DynamoDB()使用原始DynamoDB对象时,才需要指定属性类型(即"S"上键入的简单对象,{{ 1}},等等。)

使用"N",您应该能够使用这样的参数:

DocumentClient

请注意,为了保持一致性和安全性,我还将字段名称移动到const params = { TableName: 'quotient-quotes', FilterExpression: '#cat = :cat', ExpressionAttributeNames: { '#cat': 'category', }, ExpressionAttributeValues: { ':cat': category, }, }; 值。这是一个很好的做法,因为如果不这样做,某些字段名称可能会破坏您的请求。

答案 1 :(得分:0)

我一直在寻找将 KeyConditionExpression 与 FilterExpression 相结合的解决方案,最终我解决了这个问题。 其中 aws 是 uuid。 Id 是一个分配的唯一编号,前面带有文本“表单”,因此我可以告诉我有表单数据,optinSite 是这样我可以找到来自特定站点的查询。其他数据存储,这就是我需要的数据包。

也许这对你有帮助:

let optinSite   = 'https://theDomainIWantedTFilterFor.com/';
let aws = 'eu-west-4:EXAMPLE-aaa1-4bd8-9ean-1768882l1f90';
let item = {
    TableName: 'Table',
    KeyConditionExpression: "aws = :Aw and begins_with(Id, :form)",
    FilterExpression: "optinSite = :Os",
    ExpressionAttributeValues: {   
        ":Aw" : { S: aws },
        ":form" : { S: 'form' },
        ":Os" : { S: optinSite }
    }
};