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

Cam*_*ron 3 amazon-dynamodb

我在DynamoDB中有一个表:

Id: int, hash key
Name: string
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

  1. 扫描表格.这是最简单的选择,但效率最低.这张表中的数据比我经常扫描的数据要多一些.
  2. 扫描+将其缓存在内存中.但后来我不得不担心缓存失效等问题.
  3. 使Name成为一个范围键,它支持查询的starts_with函数.但是,我仍然需要扫描表,因为我想检索每个哈希键的结果,所以这不起作用.
  4. 创建一个全局二级索引,并仅使用范围键进行查询.这似乎也不可行.我可以有一个静态值的列,并使用它作为GSI的哈希键,但这似乎是一个非常丑陋的黑客.
  5. 使用像CloudSearch这样的全文搜索引擎,但这对我的用例来说似乎有点过分.

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

小智 6

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

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

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

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

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