【问题标题】:GraphQL disable filtering if filter variable is empty如果过滤器变量为空,GraphQL 禁用过滤
【发布时间】:2018-12-05 11:04:16
【问题描述】:

我有一个 Gatsby GraphQL 查询,以获取按日期排序并按类别过滤的帖子列表。

{
  posts: allContentfulPost(
    sort: {fields: [date], order: DESC},
    filter: {category: {slug: {eq: $slug}}}
  ) {
    edges {
      node {
        title {
          title
        }
        date
      }
    }
  }
}

现在当$slug 是空字符串"" 时,我明白了

{
  "data": {
    "posts": null
  }
}

有没有办法获取所有帖子?

【问题讨论】:

  • 在这种情况下,您能否尝试将$slug 设置为null 而不是""
  • @FabianSchultz 我做到了。不幸的是,在null 周围加引号和不加引号的结果相同。
  • 您找到解决问题的方法了吗?
  • 并非如此。这对我来说不再是问题,因为出于不相关的原因,我选择始终查询所有帖子并使用 JS 即时进行过滤。

标签: graphql graphql-js gatsby contentful


【解决方案1】:

您可以使用正则表达式过滤器来发挥自己的优势。如果你传递一个空表达式,那么所有的帖子都会被返回,因为一切都会匹配。

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`.
    }
  })
}

【讨论】:

  • 您的回答对我找到解决方案很有帮助。就我而言,我也使用了正则表达式,但在过滤器中我使用了术语regex 而不是eq,因此根据您的示例,它是:filter: {category: {slug: {regex: $slugRegex}}}
【解决方案2】:

这个查询是不可能的,即使@skip/@include 指令也无济于事,因为你不能将它们应用于输入字段。

我建议要么调整服务器端逻辑,以便“eq”字段中的 null 将忽略此过滤器,要么编辑正在发送的查询(不太喜欢 imo)。

您使用的 graphql 架构似乎缺少您需要的过滤支持..

【讨论】:

    【解决方案3】:

    如果有人需要 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-29
      • 1970-01-01
      • 2021-09-23
      • 1970-01-01
      • 1970-01-01
      • 2019-04-04
      • 1970-01-01
      • 2019-12-29
      相关资源
      最近更新 更多