嵌套数组(属性)的分页

Pagination on nested arrays (attributes)

我试图在社交网络的 nosql 数据库模型中遵循 "one table" 原则。但这给我带来了很多问题。
假设我的模型现在看起来像这样:

Table-Groups
{
  name: "Group1"
  topics: [
    name: "Topic1"
    posts: [
      {
        id: "tid1"
        author: "Walter White"
        message: "Hello from Post1"
        comments: [
          {
            id: "cid1"
            author: "Jessy"
            message: "Yo nice post Mr. White"
          }
          {
            id: "cid2"
            author: "Saul"
            message: "Jeze Walt"
          }
        ]
      }
      //... Many other posts here    
    ]
      //... Many other topics within the group
  ]
}
//... Not so many other groups

我可以对 post 或评论数组进行分页吗?
因为我(理论上)在 post 数组中有很多 posts,所以我将不得不读取大量数据,而实际上我只想读取最新的 10 个数据post秒。 post 中的数组注释也是如此。是否可以对这些数组进行分页?

我可以使用主题数组中的属性 "name" 作为 sortKey 吗? (topic.name)
有什么方法可以使用嵌套数组的属性作为排序键吗?在我的示例中,一个组中有很多主题。因此,使用主题名称作为排序键(甚至分区键,如果我被允许拆分 table)是有意义的。


我觉得我至少应该把 Table 一分为二。这样我就可以将主题名称用作分区键,将组名称用作排序键。但我对 nosql dbs 真的很陌生,我了解到你应该只使用一个 table。你有什么意见 ?

Would I be able to paginate the post or comments array?

没有。您的模型有一个您称为组的项目。当您的服务器 运行s GetItem 时,所有主题都会为您返回,并且在主题内,还会返回所有评论。

您的模型还有另一个大问题:您的组可以无限增加并且 DynamoDB 项目的最大大小为 400 KB。检查 this docs:

"The maximum item size in DynamoDB is 400 KB, which includes both attribute name binary length (UTF-8 length) and attribute value lengths (again binary length). The attribute name counts towards the size limit."

换句话说,有时您将无法保存更多主题或帖子。

Can I use the attribute "name" in the topic array as sortKey ? (topic.name)

没有。检查此 docs。它指出:"Each primary key attribute must be a scalar (meaning that it can hold only a single value). The only data types allowed for primary key attributes are string, number, or binary. There are no such restrictions for other, non-key attributes."

I have the feeling that I should split the Table in at least two. With that I could use topicname as partitionkey and group name as sort key.

我认为你不应该分成两个 table。您可以用这种方式为您的 DynamoDB 建模,并且只保留一个 table:

  1. 在 table 中使用 hashKeysortKey

  2. 像这样保存您的网上论坛项目:

    • hashKey: 组(它是字符串 group 而不是变量)
    • 排序键:groupId
    • 姓名:groupName
  3. 以这种方式保存您的主题项:

    • 哈希键:groupId
    • 排序键:topicId
    • 姓名:topicName
  4. 像这样保存您的帖子项目:

    • 哈希键:topicId
    • 排序键:postId
    • 作者:author
    • 留言:message
  5. 以这种方式保存您的评论项:

    • 哈希键:postId
    • 排序键:commentId
    • 作者:author
    • 留言:message

有了这个,如果你想检索单个项目,你 运行 一个带有完整键的 GetItem:hashKeyrangeKey.

相反,如果您想使用分页查询,您只需在查询中提供 hashKey 并根据需要将其限制为 10(docs 关于查询限制)。

最后,如果您想按时间查询,在您的案例中是最近的,您可以在排序键前加上 date/time。例如,2019-08-11-22-03-03_SOME_STRING。检查此 docs 关于使用时间的查询。

正如 Pedro 所说的其他评论,您很快就会陷入项目大小 >400KB 的问题。

像 dynamodb 这样的 nosql 数据库的全部意义在于你应该能够将你的系统建模(无论多么复杂)到一个单一的 table 中。然而,对 table 没有限制,但您应该能够使用单个 table.

来模拟您当前的需求

尝试将组、主题、帖子和评论分开,并使用它们的 id 作为分区键。要实现分页,您可以使用 limit 查询帖子 您可以像其他评论者指定的那样实施您的 table,如果您需要不同类型的查询,也可以添加 GSI。