如果过滤器变量为空,GraphQL 禁用过滤

Posted

技术标签:

【中文标题】如果过滤器变量为空,GraphQL 禁用过滤【英文标题】:GraphQL disable filtering if filter variable is empty 【发布时间】: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 而不是"" @F***Schultz 我做到了。不幸的是,在null 周围加引号和不加引号的结果相同。 您找到解决问题的方法了吗? 并非如此。这对我来说不再是问题,因为出于不相关的原因,我选择始终查询所有帖子并使用 JS 即时进行过滤。 【参考方案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

【讨论】:

以上是关于如果过滤器变量为空,GraphQL 禁用过滤的主要内容,如果未能解决你的问题,请参考以下文章

使用 GraphQL 变量和 Next JS 过滤数组中的数据

graphql,如何按第一个节点名称过滤?

graphql,如何按第一个节点名称进行过滤?

GraphQL/Graph.cool 查询过滤嵌套关系

plsql 检查 where 子句中至少一个变量不为空

如果值为空,postgresql 忽略过滤条件