I'm working on a blog where one blogpost can have multiple authors. I got this working with mappings between my nodes. I can query for a markdown file and get all the linked authors.
Now I'm working on a page for each author that displays all the posts he/she contributed to. How can this be done? Below you can find the query I'm currently using, but that one's not working (author.js).
I setup an example in this repo.
gatsby-config.js:
module.exports = {
...
mapping: {
"MarkdownRemark.frontmatter.authors": `AuthorYaml`,
},
...
}
gatsby-node.js:
const path = require(`path`)
const { createFilePath } = require(`gatsby-source-filesystem`)
exports.onCreateNode = ({ node, getNode, actions }) => {
const { createNodeField } = actions
if (node.internal.type === `AuthorYaml`) {
const slug = createFilePath({ node, getNode, basePath: `data` })
createNodeField({
node,
name: `slug`,
value: slug,
})
}
}
exports.createPages = ({ graphql, actions }) => {
const { createPage } = actions
return new Promise((resolve, reject) => {
graphql(`
allAuthorYaml {
edges {
node {
id
fields {
slug
}
}
}
}
}
`).then(result => {
result.data.allAuthorYaml.edges.forEach(({ node }) => {
createPage({
path: node.fields.slug,
component: path.resolve(`./src/templates/author.js`),
context: {
// Data passed to context is available
// in page queries as GraphQL variables.
slug: node.fields.slug,
id: node.id
},
})
})
resolve()
})
})
}
src/pages/blog/example-blog-post.md
---
title: "Example Blog Post"
date: "2018-08-11"
authors: [john_doe, jane_doe]
---
src/data/author.yaml
- id: john_doe
name: John Doe
- id: jane_doe
name: Jane Doe
src/templates/author.js
...
export const query = graphql`
query($id: String!) {
allMarkdownRemark(filter: { frontmatter: { authors: { in: [$id] } } } ) {
edges {
node {
...
html
...
}
}
}
}
`
it would help if you share your repo. so that i could see details and test stuff :)
did you try
export const query = graphql`
query($id: String!) {
-allMarkdownRemark(filter: { frontmatter: { authors: { in: [$id] } } } ) {
+allMarkdownRemark(filter: { frontmatter: { authors: { eq: $id } } } ) {
edges {
node {
...
html
...
}
}
}
}
`
Hi @cezarneaga, thanks for your response!
I setup an example in this repo. The build is currently failing because the query in author.js does not return any blog posts.
Changing the in: [$id] to eq: $id does not work for me. 馃槥
hmm, i think there might be an issue with implementation of elemMatch and frontmatter driven data.
the query should be of the shape:
{
allMarkdownRemark(filter:{ frontmatter:{authors: {elemMatch: { id: {eq:"jane_doe"}}}}){
...
}
because authors is of {id, name} shape not string
but this isnt the case. i think it could be a bug in how data is normalized.
i would ask for guidance from @KyleAMathews on this.
sorry i can't help more. similar normalization of data coming from an api creates expected results.
best,
C
Please create minimal reproduction repo - I was implementing elemMatch, so if it doesn't work, you should ping me ;)
---edit
Oh sorry, I've missed example in description - I'll take a look
Hi @pieh, thanks for taking a look. Please let me know if you need any help.
I am trying to do the exact same mapping on my project and struck while creating a query for listing posts created by a particular author.
I guess #7385 might be related to this and tackled together.
Maybe @pieh already had some time to take a look?
Problem here is we don't create proper filter schema for mapped fields - we need to add support for that
All right - here's is WIP working branch that enables filtering by mapped fields https://github.com/gatsbyjs/gatsby/compare/master...pieh:mapping-filter-schema - this need to be cleaned up and tests definitely need to be added (and maybe more tests need to be updated)

Until the branch is accepted and merged, do we simply filter using Array.filter on the data in JS?
Hiya!
This issue has gone quiet. Spooky quiet. 馃懟
We get a lot of issues, so we currently close issues after 30 days of inactivity. It鈥檚 been at least 20 days since the last update here.
If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!
Thanks for being a part of the Gatsby community! 馃挭馃挏
@pieh Not sure it's the same issue, but I also have problems with elemMatch:
Gatsby doesn't show errors on this query, but resulting fields are not filtered:

@godmuahaha so this actually works correctly - but probably doesn't do what you want it to do
Filter only filter outs top level nodes - so it tries to find personalJson node, that contains item with level 2. And returned node satisfy that condition. But it doesn't filter items field. What I'd assume you want is described in this feature request - https://github.com/gatsbyjs/gatsby/issues/10990
@pieh, got it! Thanks for explanation, that feature would be very useful, I have an array of ~300 items and need only one of them
Hey again!
It鈥檚 been 30 days since anything happened on this issue, so our friendly neighborhood robot (that鈥檚 me!) is going to close it.
Please keep in mind that I鈥檓 only a robot, so if I鈥檝e closed this issue in error, I鈥檓 HUMAN_EMOTION_SORRY. Please feel free to reopen this issue or create a new one if you need anything else.
Thanks again for being part of the Gatsby community!
@freiksenet @stefanprobst is this fixable now?
This should be working already:
{
allMarkdownRemark(filter: {frontmatter: {authors: {elemMatch: {id: {eq: $id}}}}}) {
edges {
node {
frontmatter {
title
authors {
id
name
}
}
}
}
}
}
Note that filtering by name should work just as well as by id:
{
allMarkdownRemark(filter: {frontmatter: {authors: {elemMatch: {name: {eq: "Jane Doe"}}}}}) {
edges {
node {
frontmatter {
title
authors {
id
name
}
}
}
}
}
}
There are other approaches to getting posts by author as well, for example you can add a posts field directly on the AuthorJson type, or add a custom root query field postsByAuthor. Some of those approaches are documented in the schema customization guide.
@gurtjun sidenote: make sure to use .map instead of .forEach here to actually display the results
Yup, I can also confirm this is working fine cc: @KyleAMathews @stefanprobst
I am trying to do exactly this with a variable list and getting a specific entry by it's type and it is not working.
my query is:
query MyQuery {
allMarkdownRemark(filter: {frontmatter: {sections: {elemMatch: {type: {eq: "pagePreview"}}}}}) {
edges {
node {
frontmatter {
sections {
linkText
page
type
content
heading
}
}
}
}
}
}
it is returning an array with all sections regardless of their type
is there a way to use createResolve to add a getByType query to the MarkdownRemarkFrontmatterSectionsFilterListInput type?
Most helpful comment
All right - here's is WIP working branch that enables filtering by mapped fields https://github.com/gatsbyjs/gatsby/compare/master...pieh:mapping-filter-schema - this need to be cleaned up and tests definitely need to be added (and maybe more tests need to be updated)