搜索DynamoDB表上的数组项

时间:2018-04-28 23:33:42

标签: indexing amazon-dynamodb denormalization

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

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

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

  1. 我是否可以在电子邮件地址上创建一个索引,该索引与人员记录有1-many关系,并且根据我在DynamoDB中的理解将其存储为数组。
  2. 此二级索引是全局还是本地?假设我有数十亿人的记录?
    1. 如果我可以将其创建为LSI或GSI,请解释每个的优点/缺点。
  3. 非常感谢你!

2 个答案:

答案 0 :(得分:2)

值得一提的是从术语开始。 DynamoDB supported data types

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

文档 - 列表,地图

设置 - 字符串集,数字集,二进制集

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

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

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

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

根据此架构,您必须执行scan,您可以使用FilterExpression运算符在您的电子邮件属性中设置CONTAINS

答案 1 :(得分:2)

Stu的回答里面有一些很好的信息,而且他是对的,你不能用一个数组它自己作为一把钥匙。

  

你可以sometimes做的是将几个变量(或一个数组)连接成一个带有已知分隔符的字符串(例如,' _'),然后将该字符串用作排序键。

我使用这个概念来创建一个由多个ISO 8061日期对象组成的复合排序键(DyanmoDB在String类型属性中将日期存储为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)的一个词

这里的问题是你仍然需要知道'辅助数据结构的分区键。 GSI / LSI可帮助您避免创建其他DynamoDB表,仅用于改善数据访问。

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

对我来说,这听起来更像是选择钥匙。

LSI(本地二级索引) 如果(对于您的查询案例)您不知道开始时的分区键(因为它似乎不是),那么本地二级索引不会有帮助 - 因为它具有相同的分区键作为基表。

GSI(全球二级指数) 全局二级索引可以帮助您可以拥有一个不同的分区密钥和排序密钥(可能是您可以“知道此查询”的分区密钥)。

因此,您可以使用电子邮件属性(可能是复合)作为GSI上的排序键,然后使用服务名称或注册阶段作为分区键。这会让你知道'用户将根据他们的进度或他们注册的服务(例如)进行分区。

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