【问题标题】:Should I use scan or query?我应该使用扫描还是查询?
【发布时间】:2018-08-28 12:11:28
【问题描述】:

我在 DynamoDB 中很难在两个日期之间选择一组条目。我的日期是字符串,格式简单为“2018-01-01”。

我应该使用查询还是扫描?我的参数看起来还好吗?该操作似乎有效,但我没有得到任何结果。我做错了什么?

这是我的代码:

// get transactions for {month} and {year}
api.get('/transaction/tab/{year}/{month}', (request) => {
  const year = request.pathParams.year
  const month = request.pathParams.month
  const params = {
    TableName: request.env.tableName,
    KeyConditionExpression: '#date between :val1 and :val2',
    ExpressionAttributeNames: {
      '#date': 'date'
    },
    ExpressionAttributeValues: {
      ':val1': {
        S: year +'-' + month + '-01'
      },
      ':val2': {
        S: year + '-' + month + '-' + getDaysInMonth(month, year)
      }
    }
  }
console.log(params)
  // post-process dynamo result before returning
  dynamoDb.query(params, (err, data) => {
    console.log(data)
    if (err) {
      console.error('Unable to query. Error:', JSON.stringify(err, null, 2))
      return 'Unable to query. Error: '+ JSON.stringify(err, null, 2)
    } else {
      console.log('Query succeeded.')
      data.Items.forEach((item) => {
        console.log(' -', item.year + ': ' + item.title)
      })
      return data.Items
    }
  })
})

【问题讨论】:

    标签: node.js amazon-web-services aws-lambda amazon-dynamodb claudiajs


    【解决方案1】:

    当您使用KeyConditionExpression 表达式时,意味着您在GSI 上使用了Query

    如果date 是分区键而不是排序键。那么,你就有问题了:

    您没有在参数中定义IndexName

    在查询操作中,您不能对分区键执行比较测试(、BETWEEN、...)。条件必须对单个分区键值执行相等测试 (=),并且可以选择对单个排序键值执行多个比较测试之一。

    例如:

    KeyConditionExpression: 'HashKey = :hkey and RangeKey > :rkey'

    您想获得一个月的transactions 吗?我认为,您必须使用以下内容创建 GSI:year-month 是 PrimaryKey(例如:2018-01、2018-02),day-createdAt 是 SortedKey(例如:28-1535429111358,...)

    查询将如上所示:

    const params = {
        TableName: request.env.tableName,
        IndexName: 'MONTH-DAY-IDX',
        KeyConditionExpression: 'year-month = :val1',
        ExpressionAttributeValues: {
          ':val1': {
            S: year +'-' + month
          },
        }
      }
    

    【讨论】:

    • 是的,我想获得一个月内的交易清单。那么,您建议将日期存储为单独的字段?我已经有一个 createdupdated 条目作为数据模型的一部分。这是交易的日期。这有点像一个寄存器。这将是一个灵活的、用户输入的值。
    【解决方案2】:

    DynamoDB 本身不支持 date/time 类型。所以我建议将日期存储为 UTC Number,又名 Unix epoch time 并使用 Query,因为它比 Scan 好得多

    快速浏览以下文章,了解如何转换为 unix 时间戳:

    https://coderwall.com/p/rbfl6g/how-to-get-the-correct-unix-timestamp-from-any-date-in-javascript

    【讨论】:

    • 是的,我考虑过。可能是我最终的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-05
    相关资源
    最近更新 更多