在GraphQL中,我有两种类型,即Author和Quotes,如下所示:
type Author {
id: Int!
name: String!
last_name: String!
quotes: [Quote!]!
}
type Quote {
id: Int!
author: Author!
quote: String!
}
我的解析器功能的一部分如下:
Author: {
quotes: ({ id }, args, { models, loaders }, info) => {
return loaders.quotesByIds.load(id);
}
}
Quote: {
author: (obj, args, { models, loaders }, info) => {
let author_id = obj.author_id;
return models.author.findById(author_id);
//return loaders.authorsById.load(obj.author_id); //for batching.
}
}
我已经将Sequelize用作数据库的ORM,而模型表示用于查询数据库的Sequelize对象。 loaders 对象是用于批量处理和缓存的DataLoader对象。
我已使用以下代码成功批量处理了报价请求:
let quotesByIds = new DataLoader(getQuotesByID);
async function getQuotesByID(authorIds){
let quotes = await models.quote.findAll({ where: { author_id: authorIds } });
let data = quotes.map((quote) => quote.get({ plain: true }));
const groupQuotes = _.groupBy(data, 'author_id');
return authorIds.map(aId => groupQuotes[aId] || []);
}
然后,我每次使用loaders.quotesByIds.load(id)获取报价。一切正常。
但是,当我使用以下查询时:
query{
authors{
id
name
quotes{
id
author{
name
}
quote
}
}
}
DataBase请求如下:
1。 Executing (default): SELECT [id], [name], [last_name] FROM [author] AS [author];
2。 Executing (default): SELECT [id], [author_id], [quote] FROM [quote] AS [quote] WHERE [quote].[author_id] IN (1, 2, 3, 4, 5, 6, 7, 8);
3。 Executing (default): SELECT [id], [name], [last_name] FROM [author] AS [author] WHERE [author].[id] = 1;
4。。Executing (default): SELECT [id], [name], [last_name] FROM [author] AS [author] WHERE [author].[id] = 2;
5。。Executing (default): SELECT [id], [name], [last_name] FROM [author] AS [author] WHERE [author].[id] = 3;
6。 Executing (default): SELECT [id], [name], [last_name] FROM [author] AS [author] WHERE [author].[id] = 4;
7。。Executing (default): SELECT [id], [name], [last_name] FROM [author] AS [author] WHERE [author].[id] = 4;
8。。Executing (default): SELECT [id], [name], [last_name] FROM [author] AS [author] WHERE [author].[id] = 4;
9。 Executing (default): SELECT [id], [name], [last_name] FROM [author] AS [author] WHERE [author].[id] = 4;
10。 Executing (default): SELECT [id], [name], [last_name] FROM [author] AS [author] WHERE [author].[id] = 4;
11。 Executing (default): SELECT [id], [name], [last_name] FROM [author] AS [author] WHERE [author].[id] = 5;
12。 Executing (default): SELECT [id], [name], [last_name] FROM [author] AS [author] WHERE [author].[id] = 6;
13。 Executing (default): SELECT [id], [name], [last_name] FROM [author] AS [author] WHERE [author].[id] = 6;
第一个查询SELECT [id], [name], [last_name] FROM [author] AS [author];
已经获取了所有作者,因此,不需要从 3到13 进行查询。
但是,此问题也可以通过实现DataLoader功能来解决。
之后,从 3到13 的查询将被批量处理为一个:
Executing (default): SELECT [id], [name], [last_name] FROM [author] AS [author] WHERE [author].[id] IN (1,2,3,4,5,6);
有一种方法可以让解析程序知道根本不要运行此查询,因为作者姓名已经存在并且已经使用 Query 1 进行了提取。