bkoodaa
bkoodaa

Reputation: 5322

GraphQL filters in GatsbyJS

I'm having trouble understanding how to write filters for GraphQL queries in GatsbyJS.

This works:

filter: { contentType: { in: ["post", "page"] }

I basically need the reverse of that, like:

filter: { "post" in: { contentTypes } } // where contentTypes is array

That doesn't work because "NAME is expected" (where "post" is in my example).

After going through GatsbyJS docs I found this:

elemMatch: short for element match, this indicates that the field you are filtering will return an array of elements, on which you can apply a filter using the previous operators

filter:{
  packageJson:{
    dependencies:{
      elemMatch:{
        name:{
          eq:"chokidar"
        }
      }
    }
  }
}

Great! That's what I need! So I try that, and I get:

error GraphQL Error Field "elemMatch" is not defined by type markdownRemarkConnectionFrontmatterTagsQueryList_2.

Keywords defined in markdownRemarkConnectionFrontmatterTagsQueryList_2 are:

Why am I limited to these keywords when more keywords such as elemMatch are mentioned in docs? Why am I not allowed to use the filter structure "element in: { array }"?

How can I create this filter?

Upvotes: 4

Views: 7764

Answers (1)

Derek Nguyen
Derek Nguyen

Reputation: 11577

Filter by value in an array

Let's say you have a markdown blog with categories as an array of string, you can filter posts with "historical" in categories like this:

{
  allMarkdownRemark(filter:{
    frontmatter:{
      categories: {
       in: ["historical"]
      }
    }
  }) {
    edges {
      node {
        id
        frontmatter {
          categories
        }
      }
    }
  }
}

You can try this query out in any of the graphiq blocks in Gatsby.js docs.


ElemMatch

I think elemMatch is only 'turned on' for fields with array of objects; something like comments: [{ id: "1", content: "" }, { id: "2", content: ""}]. This way, you can apply further filters on the fields of each comment:

comments: { elemMatch: { id: { eq: "1" } } }

Here's an example you can try out in the graphiq blocks in gatsby docs:

// only show plugins which have "@babel/runtime" as a dependency
{
  allSitePlugin (filter:{
    packageJson:{
      dependencies: {
        elemMatch: {
          name: {
            eq: "@babel/runtime"
          }
        }
      }
    }
  }) {
    edges {
      node {
        name
        version
        packageJson {
          dependencies {
            name
          }
        }
      }
    }
  }
}

Upvotes: 7

Related Questions