在 Gatsby 和 Contentful 中按日期过滤

Dom*_*ker 4 contentful graphql gatsby

如何在 Gatsby 中按日期过滤?文档暗指ltgt操作符,当我尝试使用它们时出现错误。

Dom*_*ker 6

在 Gatsby 中按日期过滤可能很棘手。许多 API 将 JSON 中的日期作为字符串发送 - 采用 ISO8601 格式。这意味着 GraphQL 也会将日期视为字符串。如果您喜欢过滤字符串相等性,这很好,但这通常不是您想要过滤日期的方式。

一个常见的用例是过滤到过去或未来的日期。在大多数情况下,我们会与今天的日期做某种less thanmore than比较。不幸的是,这不适用于 GraphQL 中的日期字符串。在ltgt运营商只适用于数字并不会为字符串的工作。

幸运的是,有一个逃生舱门 - setFieldsOnGraphQLNodeType。这允许我们获取一个内容节点,并添加我们自己的带有派生数据的字段。我们可以获取一个日期字符串,并将其解析为时间戳 - 一个数字。使用日期作为时间戳,graphql 可以做它的事情并允许ltgt过滤。

假设我们正在写一个博客,以及过滤过去发布的帖子的内容。我们可以publishedAt在 ContentModel 中添加一个datetime 字段,这将有助于我们的内容作者将来发布内容。我们可以过滤掉未来的帖子,直到我们将publishedAt日期字符串转换为数字。

这是它的外观:

exports.setFieldsOnGraphQLNodeType = ({ type }) => {
  if (type.name === `ContentfulBlogPost`) {
    return {
      publishAtTimestamp: {
        type: GraphQLFloat,
        resolve: source => {
          return new Date(source.publishAt).getTime(); 
        }
     }
   };
  }

  // by default return empty object
  return {};
};
Run Code Online (Sandbox Code Playgroud)

ContentfulBlogPost 现在有一个新字段publishedAtTimestamp,它是一个数字,这意味着您现在可以使用ltgt

  query {
    allContentfulBlogPost(
      filter: { publishedAtTimestamp: { lt: $SOME_TIMESTAMP } }
    ) {
      edges {
        node {
          id
          ...otherFields
        }
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)