Amazon dynamodb 在DynamoDB上检索列以指定文本开头的所有项

Amazon dynamodb 在DynamoDB上检索列以指定文本开头的所有项,amazon-dynamodb,Amazon Dynamodb,我在DynamoDB有一张桌子: Id: int, hash key Name: string (还有很多列,但我省略了) 通常我只是根据项目的Id提取和更新项目,这个模式可以很好地实现这一点 但是,其中一个要求是基于名称有一个自动完成下拉框。我希望能够查询DynamoDB表中以查询字符串开头的名称列的所有项 解决这个问题的SQL方法是在Name上添加一个索引,然后从Name所在的表中编写一个SELECT Id这样的查询,比如'query%',但我想不出一个DynamoDB友好的方法来实现这一

我在DynamoDB有一张桌子:

Id: int, hash key
Name: string
(还有很多列,但我省略了)

通常我只是根据项目的Id提取和更新项目,这个模式可以很好地实现这一点

但是,其中一个要求是基于名称有一个自动完成下拉框。我希望能够查询DynamoDB表中以查询字符串开头的名称列的所有项

解决这个问题的SQL方法是在Name上添加一个索引,然后从Name所在的表中编写一个SELECT Id这样的查询,比如'query%',但我想不出一个DynamoDB友好的方法来实现这一点

我已经考虑了几种解决方法:

  • 扫描表格。这是最简单的选择,但效率最低。这个表中的数据比我经常扫描的数据要多一些
  • 扫描并将其缓存在内存中。但是我不得不担心缓存失效等问题
  • 将Name设置为一个范围键,该键支持查询中的begins_with函数。但是,我仍然需要扫描该表,因为我想要检索每个散列键的结果,所以这实际上不起作用
  • 创建一个全局二级索引,并仅使用范围键进行查询。这似乎也不可能。我可以有一个带有静态值的列,并将其用作GSI的哈希键,但这似乎是一个非常难看的破解
  • 使用像CloudSearch这样的全文搜索引擎,但对于我的用例来说,这似乎是一个巨大的杀伤力

  • 这个问题有简单的解决办法吗

    问题在于DynamoDB本质上是一个键值存储,支持针对单个键的操作,您试图搜索所有不正常的值。对此的“最简单”解决方案是拥有一个已知的散列键,然后您可以直接查询它并指定条件

    例如,您可以使用
    hash\u key='name\u search'
    range\u key=begins\u with(myText)
    other\u key=begins\u with(myText)
    进行查询,并获得您正在描述的用例。对于不需要大量数据的小数据集,这将非常有效

    问题是,这不可伸缩,因为您没有遵循任何一种模式(事实上,这是一种反模式)。看一看


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

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

    然而,有一种流行的分散-聚集技术通常用于像您这样的用例。在这种情况下,您将添加一个属性
    bucket\u id
    ,并创建一个全局二级索引,其中
    bucket\u id
    作为散列键,而
    Name
    作为范围键

    bucket_id指的是一个固定范围的id或数字,具有足够的基数以确保全局二级索引分布均匀。例如,
    bucket\u id
    的范围可以是0到99。然后,在更新基表时,每当添加新条目时,都会为其分配一个介于0和99之间的随机
    bucket\u id

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


    上面的过程可能看起来有点麻烦,但它通过确保负载在固定的键范围内均匀分布,使系统/表能够很好地扩展。您可以根据需要增加bucket_id范围。为了节省成本,您可以选择只将
    键_
    投影到全局二级索引上,这样查询成本就最小化了。

    取决于您有多少记录以及您愿意花多少钱进行CloudSearch,这可能有些过头了,但它的设计正是为了满足您的需要:您是否有任何建议来选择具有“足够基数”的
    bucket\u id
    范围。是否有一些基于表中项目总数的经验法则?请参考AWS关于此策略的文档