Unlock seamless workflows and faster delivery with our latest releases - Join the deep dive

Constructing a GROQ query to filter blog posts by category in a Slack thread.

36 replies
Last updated: Oct 18, 2021
Hello!
I have some blog posts I am trying to fetch

but I want to filter them by their category.

Categories is an array of references.

I am not sure how to construct the GROQ query to filter an item by a reference matching a name within the reference.

I am constructing some sort of conditional filter on a GROQ query and was wondering if this makes sense? I do not think it works


export const getPublishedBlogPosts = (
  categories: Array<String>
) => `*[_type == "post" && published == true ${
  categories ? `&& categories[]->title [@ in ${categories.join(", ")}]` : ""
}] | order(updatedNewestFirst) {
  categories[]-> {
    title
  },
  author-> {
    name,
    title,
    image,
    slug,
  },
  type,
  slug,
  title,
  description,
  mainImage,
}`;
Which I am calling like


export const getServerSideProps = async () => ({
  props: {
    posts: await sanity.fetch(getPublishedBlogPosts(["Freelance Writing"])),
  },
});
this seems like it would work but I get some errors.


expected ']' following expression
which does not seem right as i add the
]
following the ternary
I tried basing it off the cheatsheet examples.
Oct 15, 2021, 1:08 AM
Hi User! You’re almost there. Here’s an example of querying posts that reference all tag titles in an array:

sanity.fetch(`
  *[
     _type == 'post' 
     && count(tags[@->title in $tagNames]) == count($tagNames)
  ]
`, { tagNames: ["Cat 1", "Cat 2"] })

https://groq.dev/Ax2SQe8Xcu0KonUCQKsHee
Oct 15, 2021, 2:36 AM
awesome thank you so much!
Oct 15, 2021, 2:36 AM
You can ‘expand’ an array of item like this:
categories[@->title] // ["name1", "name2"]
Then compare the title:

categories[@->title in ["name1", "name2"]] // [true, true]
This returns an array of true &amp; false, so it’s not helpful yet. You can use
count()
to get a number of
true
value:
count(categories[@->title in ["name1", "name2"]]) // 0 or 1 or 2
Here you can find posts that either reference at least 1 of the categories:

count(/*the whole thing above*/) > 1
Or all of the categories:

count(/*the whole thing above*/) == count(["name1", "name2"])
Hope that helps!
Oct 15, 2021, 2:44 AM
okay so
user G
here is what I have come up with now
*[_type == "post" && published == true && categories[@->title in $categories]] | order(updatedNewestFirst)
called like


await sanity.fetch(getPublishedBlogPosts, {
      categories: ["Freelance Writing"],
    }),
Oct 15, 2021, 2:46 AM
is this correct to get the blog posts with the category "Freelance Writing"?
Oct 15, 2021, 2:47 AM
I am at least getting an empty array now
Oct 15, 2021, 2:47 AM
and then I do the count
Oct 15, 2021, 2:47 AM
Nice, does that work? I think you’d need to wrap the
categories[@->title in $categories]
in
count(categories[@->title in $categories]) > 1
so you at least get posts that reference 1 category
Oct 15, 2021, 2:48 AM
Is still empty
Oct 15, 2021, 2:48 AM
I think it might be on my end
Oct 15, 2021, 2:48 AM
am not sure
Oct 15, 2021, 2:48 AM
gonna check my schema
Oct 15, 2021, 2:49 AM
I am gonna download the groq editor for my sanity and play w it
Oct 15, 2021, 2:50 AM
Hey User! Just to confirm, are you using
v1
or
v2021-03-25
of the API? You can see https://www.sanity.io/help/js-client-api-version and https://www.sanity.io/docs/api-versioning for details.
Oct 15, 2021, 3:51 AM
hey
user A
thanks for reaching out
Oct 18, 2021, 3:15 PM
am getting to this again now
Oct 18, 2021, 3:15 PM
gonna test in the vision
Oct 18, 2021, 3:15 PM
Yes sir
user A
it is still not working as expected
Oct 18, 2021, 3:29 PM
Yes sir
user A
it is still not working as expected
Oct 18, 2021, 3:29 PM
this is the link to the query i am trying
Oct 18, 2021, 3:29 PM
*[_type == "post" && published == true && count(categories[@->title in $categories])] {
  title
}

{
  categories: ["Freelance Writing"]
}
Oct 18, 2021, 3:30 PM
is it perhaps due to some case matching or string not being exact?
Oct 18, 2021, 3:30 PM
I could try doing a slug or something perhaps for each of the categories?
Oct 18, 2021, 3:31 PM
Oh I've just realized in the example I wrote count &gt; 1 which will never return true in your case -- have you happened to try count(...) &gt; 0?
Oct 18, 2021, 3:33 PM
Oh I've just realized in the example I wrote count &gt; 1 which will never return true in your case -- have you happened to try count(...) &gt; 0?
Oct 18, 2021, 3:33 PM
😂
Oct 18, 2021, 3:33 PM
i should look at it myself a bit closer i guess
Oct 18, 2021, 3:34 PM
my bad… let me know if that works!
Oct 18, 2021, 3:36 PM
my bad… let me know if that works!
Oct 18, 2021, 3:36 PM
ITS WORKING!!
Oct 18, 2021, 3:43 PM
😂
Oct 18, 2021, 3:43 PM
we did it
Oct 18, 2021, 3:43 PM
😂
Oct 18, 2021, 3:43 PM
thank you my man
Oct 18, 2021, 3:43 PM
Awesome!!
Oct 18, 2021, 3:44 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?