在 DynamoDB 表上搜索数组项

Blu*_*oba 4 indexing denormalization amazon-dynamodb

我需要了解如何搜索属于数组的 DynamoDB 的属性。

因此,在对表格进行非规范化时,假设一个人有许多电子邮件地址。我会在 person 表中创建一个数组来存储电子邮件地址。

现在,由于电子邮件地址不是排序键的一部分,如果我需要对电子邮件地址执行搜索以查找人员记录。我需要索引电子邮件属性。

  1. 我可以在电子邮件地址上创建一个索引吗,它与个人记录是一对多的关系,并且按照我在 DynamoDB 中的理解,它存储为一个数组。
  2. 这个二级索引是全局的还是本地的?假设我有数十亿人的记录?
    1. 如果我可以将其创建为 LSI 或 GS​​I,请解释每个的优缺点。

非常感谢!

F_S*_*O_K 5

值得一开始就正确使用术语。DynamoDB支持的数据类型

标量-字符串、数字、二进制、布尔值

文档-列表、地图

-字符串集、数字集、二进制集

我认为您建议您有一个包含电子邮件列表的属性。该属性可能如下所示

Emails: ["one@email.com", "two@email.com", "three@email.com"]
Run Code Online (Sandbox Code Playgroud)

关于此处描述的关键属性,有几个相关要点。首先,键必须是顶级属性(它们不能嵌套在 JSON 文档中)。其次,它们必须是标量类型(即字符串、数字或二进制)。

由于您的电子邮件列表不是标量类型,因此您不能在键或索引中使用它。

鉴于此架构,您必须执行scan,其中您将使用CONTAINS运算符在您的 Emails 属性上设置FilterExpression

  • 正确的。电子邮件列表是一个字符串集。您不能索引字符串集。 (2认同)

Nec*_*vil 3

Stu 的回答包含一些重要的信息,他是对的,你不能使用数组本身作为键。

\n\n
\n

您可以sometimes做的是将多个变量(或数组)连接成具有已知分隔符(例如“_”)的单个字符串,然后使用该字符串作为排序键。

\n
\n\n

我使用这个概念创建了一个由多个 ISO 8061 日期对象组成的复合排序键(DyanmoDB 将日期存储为字符串类型属性中的 ISO 8061)。我还使用了几个不是日期而是具有固定字符长度的整数的属性。

\n\n

通过使用 BETWEEN 比较,我可以单独查询连接到排序键中的每个变量,或者构建一个与所有变量作为一个组进行匹配的复杂查询。

\n\n

换句话说,数据对象可以使用如下所示的排序键: \nemail@gmail.com_email@msn.com_email@someotherplace.com

\n\n

然后您可以使用如下查询(假设您知道分区键是什么):

\n\n

SELECT * FROM Users\nWHERE User=\'Bob\' AND Emails LIKE \'%email@msn.com%\'

\n\n

您必须知道分区键才能执行查询,无论您选择什么作为排序键,也无论该排序键是如何构造的。

\n\n

我认为您真正要问的问题是我的排序键和分区键应该是什么?这具体取决于您想要进行哪些查询以及每种类型查询的使用频率。

\n\n

我发现,如果我先考虑我想要进行的查询,然后再从那里开始,我会在 DynamoDB 上取得更大的成功。

\n\n

关于二级索引 (GSI / LSI) 的说明

\n\n

这里的问题是您仍然需要“知道”辅助数据结构的分区键。GSI / LSI 可帮助您避免仅仅为了改进数据访问而创建额外的 DynamoDB 表。

\n\n

来自亚马逊:\n https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html

\n\n

对我来说,这听起来更像是选择按键的问题。

\n\n

LSI(本地二级索引) \n如果(对于您的查询情况)您不知道分区键(看起来您不知道),那么本地二级索引将无济于事\xe2\x80 \x94 因为它具有与基表相同的分区键。

\n\n

GSI(全局二级索引) \n全局二级索引可以提供帮助,因为您可以拥有不同的分区键和排序键(大概是您可以“知道”此查询的分区键)。

\n\n

因此,您可以使用电子邮件属性(可能是复合属性)作为 GSI 上的排序键,然后使用服务名称或注册阶段之类的内容作为分区键。这可以让您根据用户的进度或他们注册的服务(例如)“知道”该用户将位于哪个分区。

\n\n

GSI / LSI 仍然需要使用它们的密钥生成唯一值,因此请记住这一点!

\n