问题描述
我正在用mysql和sequelize在meteor上使用react-apollo,我仍然是JS的初学者.让我们假设我的 apollo-server 上有以下解析器功能:
I am using react-apollo on meteor with mysql and sequelize, I am still a beginner in JS.Lets assume I have the following resolver function on my apollo-server:
export default resolvers = {
Query: {
posts(_, args){
return Post.findAndCountAll({ where: args });
},
numberOfPosts(){
return /// the number of selected posts
}
}
我想从数据库中选择一些满足某些条件的数据,然后计算所选行的数量并在numberOfPosts"字段中返回它们.findAndCountAll()
返回一个对象,其中包含选定的行和计数.我想让我的 post()
只返回选定的行,而我的 numberOfPosts() 只返回选定帖子的计数.现在,两者都由 posts() 返回.
I would like to select some data from the database where some conditions are met and then count the amount of selected rows and return them in the field "numberOfPosts".findAndCountAll()
returns an object, which contains the selected rows and the count. I would like to get my post()
to return only the selected rows, and my numberOfPosts() to return only the count of the selected posts. Right now, both is returned by posts().
我的架构是:
type Post {
id: Int
date: Float
text: String
}
type NumberOfPosts{
total: Int
filtered: Int
}
type Query {
posts(
id: Ind,
offset: Int,
limit: Int,
filter: String): [Post]
numberOfPosts:[NumberOfPosts]
}
schema {
query: Query
}
目标是以下列格式接收数据:
{
"data": {
"numberOfPosts": [
{
"total": 1000,
"filtered": 21
}
],
"posts": [
{
"id": 4,
"date": 5105626122,
"text": "jzybiwutudi"
},
...
]
}
}
我目前的工作:尝试 1:
let selectedCount;
export default resolvers = {
Query: {
posts(_, args){
return Post.findAndCountAll({where: args}).then(
function (results) {
selectedCount = results.count;
return results.rows
});
},
numberOfPosts(){
return selectedCount
}
}}
所以我在解析器之外定义了一个帮助变量,并将其设置为所选行的数量,然后在 numberOfPosts()
中返回计数,这可行,但问题是, return results.rows
导致错误,我不明白为什么.
So I am defining a helping variable outside of resolvers, and set it to the number of selected rows, then the count is returned in numberOfPosts()
, which works, but the problem with this is, return results.rows
causes an error, and I do not understand why.
另一个问题是,selectedCount
总是前面的行数
another issue is, that selectedCount
is always the previous number of rows
尝试 2
另一个似乎有效的解决方案是将参数两次传递到 GraphQL 查询中,如下所示:
Another solution that seems to work is to Pass the arguments twice into the GraphQL query, like so:
{
numberOfPosts(filter: "example") {
total
filtered
}
posts(filter: "example") {
id
date
text
}
}
然后两个解析器函数都知道相同的参数,所以我可以选择和计算相同的帖子.但这对我来说看起来不对,因为我必须两次传递相同的参数,它们也会被传输两次......
Then both resolver functions know the same arguments, so I can select and count the same posts. But this looks not right to me, since I have to pass the same args twice, they will also be transmitted twice...
推荐答案
您应该更多地考虑设计以及每个查询应该做什么.这些查询不应改变数据库或全局状态.
You should think more about the design and what each of those queries should do. Those queries should not mutate the database or the global state.
你能做的最好的事情是简单地定义一个包含 total
和 filtered
的新类型,就像你在 NumberOfPosts
中所做的那样您的第一次尝试,以及帖子列表.
The best thing you can do is to simply define a new type that includes total
and filtered
, like what you did as NumberOfPosts
in your first try, and also the list of posts.
因此,您的架构将类似于:
So, your schema would be like:
type Post {
id: Int
date: Float
text: String
}
type PostList {
total: Int
filtered: Int
posts: [Post]
}
type Query {
posts(
id: Ind,
offset: Int,
limit: Int,
filter: String): PostList
}
schema {
query: Query
}
然后你解析 posts
像:
posts(_, args) {
return Post.findAndCountAll({ where: args }).then(result => {
return {
total: 1000,
filtered: result.count,
posts: result.rows
}
})
}
请注意我是如何将 1000 作为总数.您无法使用 findAndCountAll
获取总行数.如果您需要,您可以并行运行两个不同的查询并使用 Promise.all
等待他们解决.
Notice how I just put 1000 for the total number. You can not get the total number of rows with findAndCountAll
. If you that, need you can run two different queries in parallel and use Promise.all
to wait for them to be resolved.
posts(_, args) {
return Promise.all([
Post.count(),
Post.findAndCountAll({ where: args })
]).then(data => {
return {
total: data[0],
filtered: data[1].count,
posts: data[1].rows
}
})
}
上述代码也可以受益于 ES6 的解构:
The above code also could benefit from ES6's destructuring:
posts(_, args) {
return Promise.all([
Post.count(),
Post.findAndCountAll({ where: args })
]).then(([totalCount, filteredData]) => {
return {
total: totalCount,
filtered: filteredData.count,
posts: filteredData.rows
}
})
}
现在您可以运行:
query {
posts(filter:"example") {
total
filtered
posts {
id
date
text
}
}
}
并得到:
{
"data": {
"posts": {
"total": 1000,
"filtered": 21,
"posts": [
{
"id": 4,
"date": 5105626122,
"text": "jzybiwutudi"
},
...
]
}
}
}
这篇关于如何为 GraphQL 服务器设计以下解析器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!