dynamodb 中的 Typeahead 功能(而不是 begins_with)
Typeahead functionality in dynamodb (instead of begins_with)
我目前正在在线平台上工作,其中一项功能是人们可以注册并搜索其他用户。
为了更好的可用性,我想在 GUI 中实现 typeahead search,您可以在其中 search after other usernames。一切都托管在 AWS 上,因此数据库是 DynamoDB。
table 称为 users, 分区键称为“usernames”。这里的大问题是,我不能将“begins_with”与主键一起使用,因为我总是必须在查询中指定键,如下所示:
Key: { username: "mario12" }
对于我的预输入功能,很遗憾这是不允许的:
Key: { begins_with(username, "mari") }
例如,如果有人在寻找用户名为“mario12”的用户时开始输入“mari”。我将不得不 扫描 整个 table 根本不推荐这样做,因为它非常低效并且在更大的 tables 上相当昂贵。
我的解决方案:
所以我有了以下 解决方案 的想法,我已经将其实施为概念证明:
使用 2 个元素创建新的预输入查找 table:
starting_letters
作为分区键:保留在预输入搜索栏中输入的起始字母
usernames
: 以首字母开头的用户名列表
因此,如果有新用户注册,例如用户 mario12
,我会像以前一样将其保存到用户 table,但我还会在新的预输入查找中插入以下值 table:
starting_letters
usernames
mari
[mario12]
mario
[mario12]
mario1
[mario12]
mario12
[mario12]
并且当另一个用户注册时,例如用户 marionaut3
,提前输入 table 看起来像这样:
starting_letters
usernames
mari
[mario12,marionaut3]
mario
[mario12,marionaut3]
mario1
[mario12]
mario12
[mario12]
marion
[marionaut3]
mariona
[marionaut3]
marionau
[marionaut3]
marionaut
[marionaut3]
marionaut3
[marionaut3]
并且当第三个用户注册时,例如用户 marion5
,提前输入 table 如下所示:
starting_letters
usernames
mari
[mario12,marionaut3,marion5]
mario
[mario12,marionaut3,marion5]
mario1
[mario12]
mario12
[mario12]
marion
[marionaut3,marion5]
marion5
[marion5]
mariona
[marionaut3]
marionau
[marionaut3]
marionaut
[marionaut3]
marionaut3
[marionaut3]
我想你明白了....
因此,当有人开始在 GUI 中键入“mario”时,我可以查询我的预输入查找的分区键“mario”table 和return 数组[mario12,marionaut3,marion5]
。
当他继续键入“marion”时,查询 returns 数组 [marionaut3,marion5]
as “mario12” 不再匹配。
在这种情况下,我不需要昂贵的扫描,只需查询分区键即可。
我知道 - 如果有新的唯一用户名,一开始会有很多新的插入,但我的用户名和预输入功能在 4 个字符后开始工作,并且在已经插入许多用户名之后,只有新用户名结尾的新值触发新的分区键。此外,我的用户名只能包含字符 a-zA-Z0-9_- 并且长度有限,所以是的,Dynamo 应该能够处理许多(但仍然有限)变体。
现在我的问题是:您如何看待我的方法?如果您拥有 DynamoDB 并想实施预先输入搜索,还有比这更好的解决方案吗?
您的方法会奏效。然而……
让我提供一个替代方案,它涉及较少的用户名子字符串复制。将分区键设置为用户名的前四个字母。让排序键成为具有这四个字母的每个用户名。
starting_letters (PK)
usernames (SK)
mari
mario12
marionaut3
marion5
因此,每个用户名仅存储一次,并直接存储在其前四个字母的项目集合下的 table 中。您可以发出一个查询,提供正确的 starting_letters 前缀并在排序键上提供 begins_with 以查找以所有给定字母开头的用户名。
我目前正在在线平台上工作,其中一项功能是人们可以注册并搜索其他用户。
为了更好的可用性,我想在 GUI 中实现 typeahead search,您可以在其中 search after other usernames。一切都托管在 AWS 上,因此数据库是 DynamoDB。
table 称为 users, 分区键称为“usernames”。这里的大问题是,我不能将“begins_with”与主键一起使用,因为我总是必须在查询中指定键,如下所示:
Key: { username: "mario12" }
对于我的预输入功能,很遗憾这是不允许的:
Key: { begins_with(username, "mari") }
例如,如果有人在寻找用户名为“mario12”的用户时开始输入“mari”。我将不得不 扫描 整个 table 根本不推荐这样做,因为它非常低效并且在更大的 tables 上相当昂贵。
我的解决方案:
所以我有了以下 解决方案 的想法,我已经将其实施为概念证明: 使用 2 个元素创建新的预输入查找 table:
starting_letters
作为分区键:保留在预输入搜索栏中输入的起始字母usernames
: 以首字母开头的用户名列表
因此,如果有新用户注册,例如用户 mario12
,我会像以前一样将其保存到用户 table,但我还会在新的预输入查找中插入以下值 table:
starting_letters | usernames |
---|---|
mari | [mario12] |
mario | [mario12] |
mario1 | [mario12] |
mario12 | [mario12] |
并且当另一个用户注册时,例如用户 marionaut3
,提前输入 table 看起来像这样:
starting_letters | usernames |
---|---|
mari | [mario12,marionaut3] |
mario | [mario12,marionaut3] |
mario1 | [mario12] |
mario12 | [mario12] |
marion | [marionaut3] |
mariona | [marionaut3] |
marionau | [marionaut3] |
marionaut | [marionaut3] |
marionaut3 | [marionaut3] |
并且当第三个用户注册时,例如用户 marion5
,提前输入 table 如下所示:
starting_letters | usernames |
---|---|
mari | [mario12,marionaut3,marion5] |
mario | [mario12,marionaut3,marion5] |
mario1 | [mario12] |
mario12 | [mario12] |
marion | [marionaut3,marion5] |
marion5 | [marion5] |
mariona | [marionaut3] |
marionau | [marionaut3] |
marionaut | [marionaut3] |
marionaut3 | [marionaut3] |
我想你明白了....
因此,当有人开始在 GUI 中键入“mario”时,我可以查询我的预输入查找的分区键“mario”table 和return 数组[mario12,marionaut3,marion5]
。
当他继续键入“marion”时,查询 returns 数组 [marionaut3,marion5]
as “mario12” 不再匹配。
在这种情况下,我不需要昂贵的扫描,只需查询分区键即可。
我知道 - 如果有新的唯一用户名,一开始会有很多新的插入,但我的用户名和预输入功能在 4 个字符后开始工作,并且在已经插入许多用户名之后,只有新用户名结尾的新值触发新的分区键。此外,我的用户名只能包含字符 a-zA-Z0-9_- 并且长度有限,所以是的,Dynamo 应该能够处理许多(但仍然有限)变体。
现在我的问题是:您如何看待我的方法?如果您拥有 DynamoDB 并想实施预先输入搜索,还有比这更好的解决方案吗?
您的方法会奏效。然而……
让我提供一个替代方案,它涉及较少的用户名子字符串复制。将分区键设置为用户名的前四个字母。让排序键成为具有这四个字母的每个用户名。
starting_letters (PK) | usernames (SK) |
---|---|
mari | mario12 |
marionaut3 | |
marion5 |
因此,每个用户名仅存储一次,并直接存储在其前四个字母的项目集合下的 table 中。您可以发出一个查询,提供正确的 starting_letters 前缀并在排序键上提供 begins_with 以查找以所有给定字母开头的用户名。