📜  使用 graphql 在 dynamodb 中查询多个表 (1)

📅  最后修改于: 2023-12-03 15:22:11.754000             🧑  作者: Mango

# 使用 GraphQL 在 DynamoDB 中查询多个表

当需要在多个表中查询数据时,根据传统的关系型数据库设计方法,需要进行复杂的 JOIN 操作。但是,在 NoSQL 数据库 DynamoDB 中,由于不支持 JOIN 操作,我们需要采用其他的方案。本文介绍如何使用 GraphQL,在 DynamoDB 中查询多个表,以及如何进行数据关联。

需要的工具

为了使用 GraphQL 在 DynamoDB 中查询多个表,我们需要以下工具:

  • AWS Lambda
  • AWS DynamoDB
  • AWS AppSync
  • Node.js
  • GraphQL
DynamoDB 表设计

在 DynamoDB 中进行多表联合查询时,我们需要首先设计表的结构,以便于后续的查询操作。我们以一个简单的博客系统为例,需要查询文章列表和每篇文章对应的评论列表。

我们先创建两个表:

文章表

| 主键 | 内容 | | :--- | :--- | | id | 文章唯一 ID | | title | 文章标题 | | content | 文章内容 |

评论表

| 主键 | 内容 | | :--- | :--- | | id | 评论唯一 ID | | articleId | 文章唯一 ID | | content | 评论内容 |

在设计表结构时需要注意,主键必须是唯一的,用于与其他表进行关联,在 DynamoDB 中,主键可以是单一属性或复合键,复合键是指由分区键和排序键组合而成的主键。

创建 Lambda 函数

在使用 AWS AppSync 中的数据源连接 AWS Lambda 函数前,我们需要先创建 Lambda 函数。我们可以在 AWS Lambda 控制台中创建函数,并使用 Node.js 编写查询操作的代码。

const AWS = require('aws-sdk');
const dynamodbDocClient = new AWS.DynamoDB.DocumentClient();

exports.handler = async (event) => {
    const { id } = event.arguments;

    const params = {
        TableName: 'blog_posts',
        KeyConditionExpression: 'id = :id',
        ExpressionAttributeValues: { ':id': id }
    };

    const response = await dynamodbDocClient.query(params).promise();

    return response.Items[0]; 
};

在上述代码中,我们使用 AWS SDK for JavaScript 中的 DynamoDB.DocumentClient 客户端,进行 DynamoDB 数据库的查询操作,并返回查询结果。

创建 GraphQL 模型

我们使用 AWS AppSync 创建 GraphQL 模型,以便于在 DynamoDB 中进行查询。我们根据之前设计的表结构,定义如下的 GraphQL 模型:

type Post {
    id: ID!
    title: String!
    content: String!
    comments: [Comment]
}

type Comment {
    id: ID!
    articleId: ID!
    content: String!
}

type Query {
    getPost(id: ID!): Post
}

在上述代码中,我们定义了两个类型:PostCommentPost 类型包含文章的主要信息以及对应的评论列表,Comment 类型包含评论的主要信息以及所属文章的 ID 。我们还定义了查询操作 getPost,用于获取指定 ID 的文章。

创建数据源

使用 AWS AppSync 创建数据源,将 GraphQL 操作连接上述创建的 Lambda 函数。我们需要配置 Lambda 函数的名称和所属地区。

进行多表联合查询

在 Lambda 函数中查询文章列表时,我们需要查询文章表和评论表,并将它们进行关联。对于每篇文章,我们需要查询评论表,获取对应的评论信息。我们可以使用 batchGetItem 方法,一次性查询多个表。

const AWS = require('aws-sdk');
const dynamodbDocClient = new AWS.DynamoDB.DocumentClient();

exports.handler = async (event) => {
    const { id } = event.arguments;

    const params = {
        RequestItems: {
            'blog_posts': {
                Keys: [
                    { id }
                ]
            },
            'blog_comments': {
                ExpressionAttributeValues: {
                    ':articleId': id
                },
                KeyConditionExpression: 'articleId = :articleId'
            }
        }
    };

    const response = await dynamodbDocClient.batchGet(params).promise();

    const post = response.Responses.blog_posts[0];
    const comments = response.Responses.blog_comments;

    return { ...post, comments }; 
};

在上述代码中,我们使用 batchGet 方法,一次性查询文章表和评论表,并将它们进行关联。注意,在 batchGet 参数中,我们需要使用 RequestItems 对象,对每张表设置不同的参数。

结语

使用 GraphQL 在 DynamoDB 中查询多个表需要进行繁琐的表结构设计和查询操作,但是它让我们可以灵活的进行数据关联操作,为查询多个表中的数据提供了一种新的思路。