【问题标题】:DynamoDB,how to query with BEGINS_WITHDynamoDB,如何使用 BEGINS_WITH 查询
【发布时间】:2019-02-05 06:39:31
【问题描述】:

我正在使用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"
  }]

目前我的查询看起来像这样 [这给出错误][在本地 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); 
});

上面的查询可以满足我的要求。但是 欢迎任何更好的方法或解决方案。

【问题讨论】:

  • 您要解决的用例是什么,dynamodb 不支持无主键的开头。
  • @bestwishes 所以,我正在尝试获取所有文档,其中some_string 以say "77" 开头,
  • 那是计划 :) 行不通(至少用这种方法),但是 some_string 是什么,它们有什么关系,
  • 对不起,我没能以正确的方式抓住你。但是是的some_string 是一个字符串字段,可以包含一个随机字符串。喜欢56uijkhfrtu。如果你看serverless.yml你也可以得到,我已经为此添加了GSI。

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


【解决方案1】:

如果 beginwith 查询中的字符数总是随机的,我看不到使用 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 是可能的。

【讨论】:

  • number of characters in your beginswith query is always going to be random, 这将永远是随机的。现在与 id 字段也没有关系。虽然现在我使用的是.scan,它也返回了预期的数据。但似乎没有效率。
  • @saikat 是的,我的意思是,假设在您的查询中您将始终有 3 个字符,将这 3 个字符作为主键。这样您就可以查询而不是扫描。
  • 明白了,现在的情况是,当我要使用 5chars 进行搜索时,它会增加复杂性。还有这个 3,如果我让他们成为 id 的字符,任何时候它都会产生冲突。所以id 将不再是唯一的。
  • 您可以更新您的架构以将 some_string 作为排序键。之后 id 不必是唯一的,id+some_string 必须是唯一的,您可以远离 GSI1,因为这无论如何都不能解决任何目的。
  • i'm going to search with say 5chars then it will increase the complexity. 不会引起任何问题,只要您有最小查询作为 id。
猜你喜欢
  • 2023-02-20
  • 2018-03-14
  • 1970-01-01
  • 2019-09-26
  • 1970-01-01
  • 2018-06-21
  • 2012-02-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多