使用过滤器DynamoDB查询

问题描述 投票:1回答:2

我想查询使用IN过滤器DynamoDB表。我的查询工作,当我通过在一个单一的值至IN,但是当我通过在多个,我没有得到任何比赛。

这里的params对象的初始设置。

  var params = {
    TableName: "Interactions",
    IndexName: "environment-time-index",
    KeyConditionExpression: "#environment = :environment and #time between :start and :end",
    FilterExpression: "#product = :product",
    ExpressionAttributeNames: {
      "#product": "product",
      "#environment": "environment",
      "#time": "time"
    },
    ExpressionAttributeValues: {
      ":product": product,      
      ":environment": environment,
      ":start": start,
      ":end": end
    }
  };

接下来,如果用户提供了坚定的查询参数,我修改params对象,像这样。这是我使用IN操作符。

  if (req.query.firm) {
    var firms = req.query.firm;
    console.log('debug', firms);
    params.FilterExpression += " AND #firmCode IN (:firms)";
    params.ExpressionAttributeNames["#firmCode"] = "firmCode";
    params.ExpressionAttributeValues[":firms"] = firms;
  }

最后,我运行查询,像这样。

  docClient.query(params, function(err, data) {
    if (err) {
      log.error(`Unable to scan. Error: ${JSON.stringify(err, null, 2)}`);
      res.status(500).json({ error: "Oh, snap!" });
    } else {
      data.Parameters = params.ExpressionAttributeValues;
      log.info(`Scan succeeded. Received ${data.Count} items.`)
      res.send(data);
    }
  });

当公司参数包含单个值,我得到的结果返回。

Level="INFO", Date="2016-09-19 14:26:03,373", Message="batchinsight received GET for /api/history/interactions2", Product="Exhaust", Service="batchinsight", AppDomain="Exhaust_batchinsight"
debug TW7ZN
Level="INFO", Date="2016-09-19 14:26:03,623", Message="Scan succeeded. Received 19 items.", Product="Exhaust", Service="batchinsight", AppDomain="Exhaust_batchinsight"

但是,当它包含多个值,我没有得到任何结果回来。

Level="INFO", Date="2016-09-19 14:35:16,896", Message="batchinsight received GET for /api/history/interactions2", Product="Exhaust", Service="batchinsight", AppDomain="Exhaust_batchinsight"
debug TW7ZN,TEXK4
Level="INFO", Date="2016-09-19 14:35:16,991", Message="Scan succeeded. Received 0 items.", Product="Exhaust", Service="batchinsight", AppDomain="Exhaust_batchinsight"

该DynamoDB文档建议IN操作符可以接受一个逗号分隔值的列表,但我无法得到它的工作。请帮忙! http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.SpecifyingConditions.html#ConditionExpressionReference

amazon-dynamodb
2个回答
1
投票

其实,你指的是ConditionExpression参考文件,它是从FilterExpression不同。

条件表达式表示限制落实到位,当你阅读(请不要与查询/扫描混淆这一点),写数据在表格中。

实际上,您查询的表。 FilterExpression用于查询和扫描数据。

IN:两套内匹配元素检查。 AttributeValueList可以包含类型字符串,数字,或二进制(未一套类型)中的一个或多个的AttributeValue元件。这些属性是针对一个项目的一组现有类型属性进行比较。如果输入组的任何元素存在于该项目属性,表达式评估为真。

请注意,用来检查是否存在单一的一组数据类型的值。

您可以参考类似的帖子here其中OR条件来多个值在SET数据类型进行比较。

同样,如果firmCode是STRING或SET数据类型,你应该使用OR条件。


1
投票

人们很容易认为IN操作符需要一个字符串列表,但请记住,这是DynamoDB,因此,预计变量的列表。即(:string1, :string2)

我写了一个要点here以下是要点的简化版本。

const listToObjectMappings = (list) => {
    let x = {}
    list.map(item => x[':' + item] = item)
    return x
}

let statuses = ['available', 'in-transit', 'delivered']
let mappings = listToObjectMappings(statuses)
let joined = Object.keys(mappings).join();

query = {
    FilterExpression: '#stat IN (' + joined + ')',
    ExpressionAttributeNames: {
        '#stat' : 'status'
    },
    ExpressionAttributeValues: mappings
}

编辑:要点实际上是更安全的。这个版本将不包含重复的值列表工作。但是,如果每个项目都是独特的,然后它的罚款。

© www.soinside.com 2019 - 2024. All rights reserved.