在 DynamoDB 上搜索数组项 table

searching on array items on a DynamoDB table

我需要了解如何搜索作为数组一部分的 DynamoDB 的属性。

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

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

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

非常感谢!

值得从正确的术语入手。 DynamoDB supported data types

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

文档 - 列表、地图

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

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

Emails: ["one@email.com", "two@email.com", "three@email.com"]

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

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

鉴于此架构,您必须执行 scan, in which you would set the FilterExpression on your Emails attribute using the CONTAINS 运算符。

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

What you CAN sometimes do is concatenate several variables (or an Array) into a single string with a known seperator (maybe '_' for example), and then use that string as a Sort Key.

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

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

换句话说,数据对象可以像这样使用排序键: 电子邮件@gmail.com_email@msn.com_email@someotherplace.com

然后你可以这样查询(假设你知道分区键是什么):

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

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

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

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

浅谈二级索引 (GSI / LSI)

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

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

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

LSI(本地二级索引) 如果(对于您的查询案例)您不知道开始的分区键(看起来您不知道)那么本地二级索引将无济于事——因为它具有相同的分区键作为基础 table.

GSI(全球二级指数) 全局二级索引 可以 提供帮助,因为您可以拥有不同的分区键和排序键(大概是您可以 'know' 用于此查询的分区键)。

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

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