-
Notifications
You must be signed in to change notification settings - Fork 10.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
filter mapped data #4614
Comments
This is what we do for gatsbyjs.org. I assume you've looked at our implementation there? |
I looked again and it looks like you guys are doing the filtering in JavaScript rather than your query. {allMarkdownRemark.edges.map(({ node }) => {
if (node.frontmatter.author) {
if (node.frontmatter.author.id === contributor.id) {
return (
<BlogPostPreviewItem
post={node}
key={node.fields.slug}
css={{ marginBottom: rhythm(2) }}
/>
)
}
}
})} |
I somehow missed this is about filtering mapped fields. Yeah currently gatsby doesn't support that properly - we create input schema (types used in filters) using data without handling mapping, but actual filtering is done using mapped types, so this can't work right now. To make this work, we would need to adjust input schema for mapped types here - https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/src/schema/infer-graphql-input-fields.js#L229 . For reference this is how mapping is handled in output types - https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/src/schema/infer-graphql-type.js#L344 . If you feel like creating PR to fix this I can guide you through it. |
@pieh I can take a look at this tonight and see if I can figure it out. |
Any news on this? I think this would be a really useful feature |
Due to the high volume of issues, we're closing out older ones without recent activity. Please open a new issue if you need help! |
@rametta, @nrdobie—not sure when this was implemented, but what you ask for is now possible. Your GraphQL query query author {
allMarkdownRemark(
filter: {
frontmatter: {
author: { eq: "nicholas.dobie" }
}
}
) {
totalCount
}
} now returns 1, as expected. I stumbled upon this issue when looking how to filter a mapped one-to-many GraphQL field, and am documenting my findings here for future Gatsby aficionados. If this matches your description, feel free to read on... 😄 More Complicated Case: Filtering One-to-Many Mapped FieldLooking at the code <Link to={`/tags/${kebabCase(tag.fieldValue)}/`}>
{tag.fieldValue} ({tag.totalCount})
</Link> documented in Creating Tags Pages for Blog Posts, I thought hmm...
To accomplish this, I created a custom GraphQL type module.exports = {
plugins: [...],
mapping: {
'MarkdownRemark.frontmatter.tags': 'PostTag.tag',
},
}; Then, I implemented the code to create exports.onCreateNode = async ({ node, getNode, actions, createContentDigest }) => {
const { createNode } = actions;
if (node.internal.type === 'MarkdownRemark') {
// Create new nodes for post tags.
node.frontmatter.tags.forEach(tag => createNode({
tag,
// The slug will get set later.
slug: '',
// NOTE: Tag ID is unique per tag.
id: `post-tag-${tag}`,
parent: null,
children: [],
internal: {
type: 'PostTag',
contentDigest: createContentDigest(''),
},
}));
}
// This triggers only once for each post tag, rather than once per post per tag.
if (node.internal.type === 'PostTag') {
// Compute tag slug exactly once.
node.slug = `/tags/${kebabCase(node.tag)}/`;
}
}; With this in place, the GraphQL queries to power the example in Creating Tags Pages for Blog Posts change as follows:
The Gatsby GraphQL Playground was extremely helpful in helping to figure out the right filter to use. Addendum: Computing the Slug Only Once Per TagYou may have noticed how if (node.internal.type === 'PostTag') {
node.slug = ...;
} Even though But because modifying a field on a GraphQL node post-creation, even when donw from the same plugin, is discouraged (keep me honest if that's not so), I thought an alternative to this is to query the exports.sourceNodes = async ({ graphql, actions, createContentDigest }) => {
const { createNode } = actions;
const { data } = await graphql(`
query {
allMarkdownRemark {
group(field: frontmatter___tags) {
fieldValue
}
}
}
`);
data.allMarkdownRemark.group.forEach(tag => createNode({
tag,
slug: `/tags/${node.tag.toLowerCase().replace(/ /g, '-')}/`,
id: `post-tag-${tag}`,
parent: null,
children: [],
internal: {
type: 'PostTag',
contentDigest: createContentDigest(''),
},
}));
}; However, this does not work because it seems that the mapping from
Furthermore, the Gatsby Node helpers |
Description
I am trying to create a
/blog/authors/{authorID}/
page that will show author details and posts by the author.Steps to reproduce
gatsby-config
data/authors.yaml
blog/2016-08-13-post-one.md
Expected result
In GraphiQL I would expect this
Actual result
I get an error if I use that query but if I do the documented filter I get this
Environment
npm list gatsby
):1.9.232
gatsby --version
):1.1.28
8.9.3
macOS 10.12.6
The text was updated successfully, but these errors were encountered: