【问题标题】:Getting related news by tags in Gatsby and GraphQL通过 Gatsby 和 GraphQL 中的标签获取相关新闻
【发布时间】:2021-08-16 18:11:04
【问题描述】:

我一直在尝试获取 GraphQL 文章的相关新闻。 每篇文章都有 1 个或多个标签,根据这些标签,它需要找到最多 3 篇具有新查询的相关文章。

任何帮助将不胜感激。

我的查询如下所示:

    strapiArticles(Slug: { eq: $slug }) {
        strapiId
        Title
        Date
        Content
        tags {
            tag
            slug
        }
        Image {
            publicURL
        }
    }
}

标签位看起来像:

"tags": [
    {
      "tag": "Tag 1",
      "Slug": "tag-1"
    },
    {
      "tag": "Tag 2",
      "Slug": "tag-2"
    }
]

我尝试在上下文中传递标签,但 Gatsby 不支持上下文中的数组或对象。像这样:

createPage({
      path: `news/${edge.node.Slug}`,
      component: path.resolve("src/templates/news-post.js"),
      context: {
        tag: edge.node.tags,
        slug: edge.node.Slug,
      }
    })

【问题讨论】:

    标签: javascript reactjs graphql gatsby


    【解决方案1】:

    但 Gatsby 不支持上下文中的数组或对象。

    那不是真的。您可以通过上下文发送一组标签,但您需要先准备好数据:

       let allTagsFromNode= edge.node.tags.map(tag=> tag.tag);
    

    这应该返回结构中特定新的所有标记名称 (tag),例如 ["Tag 1", "Tag 2"]。如果需要,稍微调整一下以获得一个简单的一维数组。

    createPage({
          path: `news/${edge.node.Slug}`,
          component: path.resolve("src/templates/news-post.js"),
          context: {
            allTagsFromNode,
            slug: edge.node.Slug,
          }
        })
    

    注意:因为你发送allTagsFromNode的key与value相同,所以可以省略allTagsFromNode: allTagsFromNode发送

    然后,在您的 news-post.js 模板中,您的查询应如下所示:

    export const newsData = graphql`
        query getNewsInformation ($slug: String!, $author: String, $allTagsFromNode: [String!]) {
            ## your news query
            relatedArticles: strapiArticles(
                filter: {
                  tags: {elemMatch: {tag: {in: $allTagsFromNode}}}, 
                  Slug: {ne: $slug}},
                limit: 3) {
                edges {
                    node {
                      ## your node fields
                    }
                }
            }
        }
    `;
    

    在调整查询以使其适应您的需求(因为我不知道您的数据结构如何)以及添加新闻查询时,重要的是您通过$allTagsFromNode 发送标签,声明为字符串数组(称为list in GraphQL):

    $allTagsFromNode: [String!]
    

    现在,您可以从所有文章中查询和过滤以获取相关新闻:

    relatedArticles: strapiArticles(
        filter: {
           tags: {elemMatch: {tag: {in: $allTagsFromNode}}}, 
           Slug: {ne: $slug}},
        limit: 3)
    

    您现在正在过滤包含在 allTagsFromNode 列表中的所有标记名称 (tag)。

    同样重要的是要注意,您不希望将同一篇文章列为相关文章,这就是您在 Slug: {ne: $slug}} 中省略它的原因(使用 ne 过滤器)。

    【讨论】:

    • 感谢您的详细回复!它有很大帮助,我觉得我很接近。当我添加最后一个查询时,我确实收到错误“frontmatter is not defined in type”。我试过这个:filter: { tags: { in: $allTagsFromNode }, Slug: { ne: $slug } } 但这也不起作用。我收到“字段'in'未按类型定义”的错误
    • 过滤器应如下所示:filter: { tags: {tag: { in: $allTagsFromNode}}, slug: { ne: $slug }},。请记住,您的标签名称称为tag(在tags 内)并且是与allTagsFromNode 匹配的字段。此外,现在localhost:8000/___graphql 中的问题是反复试验的问题,因为现在问题与您的数据结构密切相关。
    • 显然我的过滤器必须是:filter: {tags: {elemMatch: {tag: {in: $allTagsFromNode}}}, Slug: {ne: $slug}}。这似乎现在可以工作了,谢谢!
    猜你喜欢
    • 2014-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-12
    • 2016-08-13
    • 2018-08-19
    • 1970-01-01
    相关资源
    最近更新 更多