如果过滤变量为空,GraphQL 禁用过滤
GraphQL disable filtering if filter variable is empty
我有一个 Gatsby GraphQL 查询,用于查询按日期排序并按类别过滤的帖子列表。
{
posts: allContentfulPost(
sort: {fields: [date], order: DESC},
filter: {category: {slug: {eq: $slug}}}
) {
edges {
node {
title {
title
}
date
}
}
}
}
现在当 $slug
是空字符串 ""
时,我得到
{
"data": {
"posts": null
}
}
有没有办法获取所有帖子?
此查询不可能,即使 @skip/@include 指令也无济于事,因为您无法将它们应用于输入字段。
我建议要么调整服务器端逻辑,以便 'eq' 字段中的 null 将忽略此过滤器,要么编辑正在发送的查询(imo 不太有利)。
您使用的 graphql 模式似乎缺少您需要的过滤支持..
您可以使用正则表达式过滤器来发挥您的优势。如果您传递一个空表达式,那么将返回所有帖子,因为所有内容都会匹配。
query Posts($slugRegex: String = "//"){
posts: allContentfulPost(
sort: {fields: [date], order: DESC},
filter: {category: {slug: {eq: $slugRegex}}}
) {
# Rest of the query.
}
}
默认情况下,将返回所有帖子(如果未传递任何内容,$slugRegex
是一个空的正则表达式)。当 $slugRegex
成为一个有意义的表达式时,只有匹配的帖子才会显示。
至于传递值,我假设您正在使用 gatsby-node.js
创建页面。既然如此,就这么简单:
// gatsby-node.js
exports.createPages = async ({ actions }) => {
const { createPage } = actions
// Create a page with only "some-slug" posts.
createPage({
// ...
context: {
slugRegex: "/some-slug/"
}
})
// Create a page with all posts.
createPage({
// ...
context: {
// Nothing here. Or at least no `slugRegex`.
}
})
}
如果有人需要针对 Gatsby 以外的其他系统的解决方案,可以使用 @skip
和 @include
.
来完成
fragment EventSearchResult on EventsConnection {
edges {
cursor
node {
id
name
}
}
totalCount
}
query Events($organizationId: UUID!, $isSearch: Boolean!, $search: String!) {
events(condition: { organizationId: $organizationId }, first: 100)
@skip(if: $isSearch) {
...EventSearchResult
}
eventsSearch: events(
condition: { organizationId: $organizationId }
filter: { name: { likeInsensitive: $search } }
first: 100
) @include(if: $isSearch) {
...EventSearchResult
}
}
然后在您的客户端代码中,您将向查询提供 search 和 isSearch 并获取您的事件,例如:
const events = data.eventsSearch || data.events
我有一个 Gatsby GraphQL 查询,用于查询按日期排序并按类别过滤的帖子列表。
{
posts: allContentfulPost(
sort: {fields: [date], order: DESC},
filter: {category: {slug: {eq: $slug}}}
) {
edges {
node {
title {
title
}
date
}
}
}
}
现在当 $slug
是空字符串 ""
时,我得到
{
"data": {
"posts": null
}
}
有没有办法获取所有帖子?
此查询不可能,即使 @skip/@include 指令也无济于事,因为您无法将它们应用于输入字段。
我建议要么调整服务器端逻辑,以便 'eq' 字段中的 null 将忽略此过滤器,要么编辑正在发送的查询(imo 不太有利)。
您使用的 graphql 模式似乎缺少您需要的过滤支持..
您可以使用正则表达式过滤器来发挥您的优势。如果您传递一个空表达式,那么将返回所有帖子,因为所有内容都会匹配。
query Posts($slugRegex: String = "//"){
posts: allContentfulPost(
sort: {fields: [date], order: DESC},
filter: {category: {slug: {eq: $slugRegex}}}
) {
# Rest of the query.
}
}
默认情况下,将返回所有帖子(如果未传递任何内容,$slugRegex
是一个空的正则表达式)。当 $slugRegex
成为一个有意义的表达式时,只有匹配的帖子才会显示。
至于传递值,我假设您正在使用 gatsby-node.js
创建页面。既然如此,就这么简单:
// gatsby-node.js
exports.createPages = async ({ actions }) => {
const { createPage } = actions
// Create a page with only "some-slug" posts.
createPage({
// ...
context: {
slugRegex: "/some-slug/"
}
})
// Create a page with all posts.
createPage({
// ...
context: {
// Nothing here. Or at least no `slugRegex`.
}
})
}
如果有人需要针对 Gatsby 以外的其他系统的解决方案,可以使用 @skip
和 @include
.
fragment EventSearchResult on EventsConnection {
edges {
cursor
node {
id
name
}
}
totalCount
}
query Events($organizationId: UUID!, $isSearch: Boolean!, $search: String!) {
events(condition: { organizationId: $organizationId }, first: 100)
@skip(if: $isSearch) {
...EventSearchResult
}
eventsSearch: events(
condition: { organizationId: $organizationId }
filter: { name: { likeInsensitive: $search } }
first: 100
) @include(if: $isSearch) {
...EventSearchResult
}
}
然后在您的客户端代码中,您将向查询提供 search 和 isSearch 并获取您的事件,例如:
const events = data.eventsSearch || data.events