当前位置: 首页 > 知识库问答 >
问题:

正在检索AppSync架构中的嵌套信息数组

濮阳旭东
2023-03-14

我已经在GraphQL AppSync查询上制定了一个相当复杂的DynamoDB解析器链。我很想知道的是,我是否可以以一种需要更少DynamoDB查询的方式设计它。

以下是我的GraphQL模式:

type Tag {
    PartitionKey: ID!
    SortKey: ID!
    TagName: String!
    TagType: String
}

type Model {
    PartitionKey: ID!
    Name: String
    Version: Int
    FBX: String
    # ms since epoch
    CreatedAt: AWSTimestamp
    Description: String
    Tags: [String]
}

type Query {
    GetAllModels(count: Int, nextToken: String): PaginatedModels!
}

这是我正在进行的查询:

query GetAllModels{
  GetAllModels {
    Models {    
        PartitionKey        
        Name
        Version
        CreatedAt
        Description
        Tags {
          TagName
          TagType
        }
    }
  }
}

我的DynamoDB表设置如下:

PartionKey | SortKey       | TagName | TagType | ModelName | Description
Model-0    | Model-0       |                     ModelZero | Blah Blah   
Model-0    | Tag-Pine      |
Model-0    | Tag-Apple     |
Tag-Pine   | Tag-Pine      | Pine    | Tree
Tag-Apple  | Tag-Apple     | Apple   | Fruit

因此,在我的解析器中,我将:

>

接下来,在模型对象中有一个附加到“标记”的解析器。这将使用两个表达式进行查询。一个用于PartitionKey=源。第一步和第二步,SortKey以“Tag-”开头,这将获得模型上的所有标记。

接下来,标记对象上有两个解析器。一个在标记名上,另一个在标记类型上。它们使用PartitionKey=source直接执行GetItem以获取相应的值。排序和html" target="_blank">排序键=源。SortKey设置为键。

因此,每个扫描的模型最终会向DynamoDB发出3个以上的查询。这对我来说似乎有点过分。但我看不到任何其他方法可以做到这一点。是否有某种方法可以在一个查询中同时获取标记名和标记类型?

有没有更好的方法来解决这个问题?

共有1个答案

哈雅珺
2023-03-14

我看到了一些我个人会改变的事情。首先,我将避免嵌套的DynamoDB扫描操作。其中至少有一个可以替换为更快的查询操作。第二,我会考虑重新考虑如何存储数据。目前,没有列出模型对象的好方法

为什么没有列出模型对象的好方法?

假设每个模型对象都有多个标记,那么您将有一个由模型对象稀疏填充的表。i、 e.在100行中,您可能有20-50个模型,这取决于平均模型有多少个标签。在DynamoDB中,表根据分区键进行拆分,使共享同一分区键的行彼此相邻存储,以加快查询操作。在您的设置中,分区键本质上是单个模型对象的唯一id,这意味着我们可以轻松获得单个模型对象。您还可以快速获取单个对象的标记,因为这些记录也在附近。

问题。

DynamoDB扫描操作一次查看一个分区,读取请求限制允许的记录数,如果限制足够大,则读取所有记录,然后仅在从各个分区读取记录后,在返回最终结果之前应用过滤器表达式。这意味着您可能需要前10个模型,但由于限制是在扫描过滤器之前应用的,因此您很可能只得到1个模型(如果一个模型有9个或更多的标签,这将在DynamoDB读取第一个分区时耗尽限制)。当来自许多不同的数据库系统时,这可能看起来很奇怪,这是其设计的一个重要考虑因素。

以下是解决此问题的两种解决方案:

1.将模型存储在一个表中,将标签存储在另一个表中。

像DynamoDB这样的NoSQL数据库允许您在同一个表中存储多种类型的数据,但将它们拆分出来并没有什么错。传统上,在缺少连接操作或类似操作的NoSQL数据库中处理多个表可能会很痛苦,但幸运的是,我们可以使用GraphQL来“连接”数据。使用这种方法,模型表有一个名为“id”的分区键,您的GetAllModels解析器仍然是一个扫描,但这次是在模型表上。这样,表格就不会稀疏,当您要求10个模型时,您将得到10个模型。标记表的分区键应为modelId,排序键应为tagId。然后在模型上有一个解析器。标记字段,该字段对标记表进行查询,并查找modelId==$ctx的行。来源id。

这就是作为amplify cli的一部分发布的新graphql转换工具中@model和@connection的工作原理。您可以在这里看到更多内容,尽管文档的编写仍在改进中。https://aws-amplify.github.io/amplify-js/media/api_guide

2、将模型和标签存储在同一个表中,但更改键结构。

如果您可以可靠地说,每种数据类型(例如模型)的数据量将少于10GB,那么这种方法就会起作用

我相信还有很多方法可以做到这一点,但希望这有助于指出正确的方向。

 类似资料:
  • 我试图从API调用中检索数据并将其传递给另一个服务。我收到的数据是在一个特定的JSON结构,我想把它映射到一个结构,但没有多层次的数据。我尝试了点符号来访问更深的值,但它不起作用。 基本上,我试图得到一个包含一系列“问题”(key、self、description)的结构,但没有“fields.description”结构。 JSON: 结构: 预期/期望的结构: 有可能吗?如果是,怎么做?使用嵌

  • 我正在尝试使用GenericData将avro数据生成到Kafka中。记录,但我得到以下异常: 线程“main”组织中出现异常。阿帕奇。阿夫罗。AvroRuntimeException:不是有效的架构字段:emailAddresses。电子邮件 这是我的模式: 我的Java代码如下: 有人知道如何在avro记录中放入嵌套值吗?

  • 问题内容: 我正在努力从格式如下的JSON文件中检索一些值: 我尝试了不同的方法(json,gson,jayway- JsonPath),但是我无法从“属性”数组中获取值,只能从第一个数组中获取值。我不知道如何指定“属性”是一个JSONArray而不是一个JSONObject或如何为其设置正确的路径。这是我正在玩的最后一个代码,当它找到一个数组时停止: 我想做的就是获得卢卡斯或布兰登的价值。任何帮

  • 我正在努力从JSON文件中检索一些值,格式如下: 我尝试过不同的方法(json、gson、jayway JsonPath),但我无法从“属性”数组中获取值,只能从第一个数组中获取值。我不知道如何指定“attribute”是JSONArray而不是JSONObject,也不知道如何设置它的正确路径。这是我玩的最后一个代码,它在创建数组时停止: 我想做的是得到卢卡斯或布兰登的价值观。任何帮助都将不胜感

  • 问题内容: 是否可以从框架对象中检索任何类信息?我知道如何获取文件(frame.f_code.co_filename),函数(frame.f_code.co_name)和行号(frame.f_lineno),但也希望能够获取活动对象的类的名称框架的实例(如果不在实例中,则为None)。 问题答案: 我不相信,在框架对象级别上,没有任何方法可以找到已被调用的实际python函数对象。 但是,如果您的

  • 问题内容: 我已经开始使用https://mholt.github.io/json-to-go/将API JSON转换为go结构,但我真的很喜欢它,但是我仍然坚持如何在Report Definition结构中初始化Filters数组结构如下所示。 我似乎无法引用在Filters结构甚至是Filters结构中声明的项,以创建新的Filter项目并将其附加到Filters。 是否可以使用原样编写的Re