DynamoDB,如何使用BEGINS_WITH查询

时间:2019-02-05 06:39:32

标签: amazon-dynamodb serverless-framework dynamodb-queries documentclient

我正在使用DocumentClient进行查询。 并在DynamoDb中使用无服务器框架。

我正在尝试使用BEGINS_WITH查询而不提供任何主键。

这是我的数据的样子:

[
  {
    id: 1,
    some_string: "77281829121"
  },
  {
    id: 2,
    some_string: "7712162hgvh"
  },
  {
    id: 3,
    some_string: "7212121"
  }
]

这是我的serverless.yml [我想是表配置]:

Resources:
 IPRecord:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        TableName: ${file(./serverless.js):Tables.IPRecord.name}
        BillingMode: PAY_PER_REQUEST
        AttributeDefinitions:
          - AttributeName: 'id'
            AttributeType: 'S'
          - AttributeName: 'some_string'
            AttributeType: 'S'
        KeySchema:
          - AttributeName: 'id'
            KeyType: 'HASH'
        GlobalSecondaryIndexes:
          - IndexName: ${file(./serverless.js):Tables.IPRecord.index.ID}
            KeySchema:
              # ...some more index goes here
              - AttributeName: 'some_string'
                KeyType: 'RANGE'
            Projection:
              ProjectionType: 'ALL'

问: 我想使用DocumentClinet查询some_string的前几个元素。 这将返回所有匹配的文档。 像在这种情况下,我想查询{some_string:"77"},它将返回

 [{
    id: 1,
    some_string: "77281829121"
  },
  {
    id: 2,
    some_string: "7712162hgvh"
  }]

当前,我的查询如下所示[这会产生错误] [在Local DynamoDB JS shell中运行]:

var params = {
    TableName: '<TABLE_NAME>',
    IndexName: '<INDEX_NAME>',
    KeyConditionExpression: 'begins_with(some_string,:value)',
    ExpressionAttributeValues: { 
      ':value': '77'
    }
};
docClient.query(params, function(err, data) {
    if (err) ppJson(err);
    else ppJson(data); 
});

似乎上述查询需要一个主键,在我的情况下为id。如果我通过了,那么它将指向一个文档。

这是我到目前为止所取得的成就:

var params = {
    TableName: '<TABLE_NAME>',
    FilterExpression: 'begins_with(some_string,:value)',
    ExpressionAttributeValues: { 
      ':value': '77'
    },
    Select:'COUNT' //as i only required COUNT
};
docClient.scan(params, function(err, data) {
    if (err) ppJson(err);
    else ppJson(data); 
});

以上查询符合我的要求。但是 总是欢迎任何更好的方法或解决方案。

1 个答案:

答案 0 :(得分:0)

如果beginswith查询中的字符数总是随机的,那么我看不到用dynamodb解决它的选项。

但是,至少要有3个字符。那么您可以执行以下操作。

将您的dynamodb模式更新为

 IPRecord:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        TableName: ${file(./serverless.js):Tables.IPRecord.name}
        BillingMode: PAY_PER_REQUEST
        AttributeDefinitions:
          - AttributeName: 'id'
            AttributeType: 'S'
          - AttributeName: 'some_string'
            AttributeType: 'S'
        KeySchema:
          - AttributeName: 'id'
            KeyType: 'HASH'
          - AttributeName: 'some_string'
            KeyType: 'RANGE'

而不是存储

[
  {
    id: 1,
    some_string: "77281829121"
  },
  {
    id: 2,
    some_string: "7712162hgvh"
  },
  {
    id: 3,
    some_string: "7212121"
  }
]

另存为

[
  {
    id: 772,
    uniqueid:1,
    some_string: "77281829121"
  },
  {
    id: 771,
    uniqueid:2,
    some_string: "7712162hgvh"
  },
  {
    id: 721,
    uniqueid:3,
    some_string: "7212121"
  }
]

id始终是原始some_string的前3个字符。

现在,假设您必须查询以abcx开头的所有项目

select * where id=abc and some_string startswith abcx

,但您应始终尝试在id中包含更多字符,以便随机分配负载。例如,如果只有2个字符,则只能有36 * 36个ID。如果只有3个字符,则可以有36 * 36 * 36个ID。