Home Articles

使用DynamoDB上以指定文本开头的列检索所有项目

Asked
Viewed 1653 times
3

我在DynamoDB中有一个表:

Id: int, hash key
Name: string

(还有更多列,但我省略了它们)

通常我只是通过他们的Id拉出并更新项目,这个架构可以正常工作 .

但是,其中一个要求是根据名称生成一个自动完成下拉框 . 我希望能够在此DynamoDB表中查询以查询字符串开头的Name列的所有项目 .

解决这个问题的SQL方法是在Name上添加一个索引,然后编写一个像SELECT Id FROM table WHERE Name LIKE'query%'这样的查询,但我无法弄清楚这种方法是否支持DynamoDB .

我考虑了几种方法来解决这个问题:

  • 扫描表格 . 这是最简单的选择,但效率最低 . 这张表中的数据比我经常扫描的数据要多一些 .

  • 扫描将其缓存在内存中 . 但后来我不得不担心缓存失效等问题 .

  • Make Name是一个范围键,它在查询中支持 begins_with 函数 . 但是,我真的很有效 .

  • 创建一个全局二级索引,并仅使用范围键查询它 . 这似乎也不可行 . 我可以有一个静态值的列,并使用它作为GSI的哈希键,但这似乎是一个非常丑陋的黑客 .

  • 使用像CloudSearch这样的全文搜索引擎,但这似乎对我的用例来说太过分了 .

这个问题有一个简单的解决方案吗?

2 Answers

  • 5

    今天DynamoDB的Query操作不直接支持您描述的用例 - DynamoDB通常要求您指定一个hashkey,然后相应地查询范围键 .

    但是,有一种流行的分散 - 聚集技术,通常用于像你这样的用例 . 在这种情况下,您将添加一个属性 bucket_id 并创建一个全局二级索引,其中 bucket_id 作为哈希键, Name 作为范围键 .

    bucket_id指的是固定范围的ID或数字,具有足够的基数以确保您的全局二级索引分布均匀 . 例如, bucket_id 的范围可以是0到99.然后在更新基表时,无论何时添加新条目,都会为其分配0到99之间的随机 bucket_id .

    在自动完成查询期间,应用程序将为每个bucket_id值(0到99)发送100个单独的查询(分散),并在范围键名称上使用 BEGINS_WITH . 检索结果后,应用程序必须组合100组响应并根据需要重新排序(收集) .

    上述过程看起来有点麻烦,但它可以确保负载均匀分布在固定的密钥范围内,从而使您的系统/表能够很好地扩展 . 您可以根据需要增加bucket_id范围 . 为了节省成本,您可以选择将 KEYS_ONLY 投影到全局二级索引上,从而最大限度地减少查询成本 .

  • 2

    问题是DynamoDB本质上是一个键值存储,支持针对单个键的操作,并且您正在尝试搜索所有不能正常工作的值 . "simplest"解决方案是使用已知的哈希键,然后您可以直接 Query 指定条件 .

    例如,您可以使用 hash_key='name_search'range_key=begins_with(myText)other_key=begins_with(myText) 进行查询,并获取您正在描述的用例 . 这适用于不需要大量provisioned RCUs的小型数据集 .

    问题是这不会扩展,因为你没有关注任何DynamoDB best practices(事实上,这是一个反模式) . 看看Understand Partition Behavior documentation

    我的建议是使用不同的服务/解决方案来实现这一目标,而不是试图将DynamoDB压缩到这个用例中 .

Related