How to reference a field in a Groq query in another part of the query without using a variable passed.

6 replies
Last updated: Sep 21, 2023
I’m looking to reference a field in a groq query in another part of the query, but without using a variable passed.
I’ve got a query which gets articles based on slug, one of the fields it pulls is the ‘categoryTitle’. Now i also have a ‘relatedArticles’ query in the same query which pulls articles based if its not the slug of the hero article, ideally i want to be able to use the categoryTitle from the hero post to filter the ‘related articles’ (see screenshot below) to only get articles that have the same categoryTitle - any idea of how to do this?
AI Update

Perfect! You need to use the parent operator (^) in GROQ. This operator lets you reference values from the parent scope when you're inside a nested query.

Here's how you'd apply it to your use case:

*[_type == "article" && slug.current == $slug][0]{
  title,
  categoryTitle,
  // ... other fields
  "relatedArticles": *[
    _type == "article" && 
    slug.current != ^.slug.current && 
    categoryTitle == ^.categoryTitle
  ][0...3]{
    title,
    slug,
    categoryTitle
  }
}

The key part is ^.categoryTitle - the caret (^) tells GROQ to look up to the parent scope (your hero article) and grab its categoryTitle field. Similarly, ^.slug.current references the hero article's slug so you can exclude it from the related articles.

You can even chain multiple parent operators if you need to go up multiple levels in scope - like ^.^.fieldName would go up two levels.

Important note: There was a bug with the parent operator that was fixed in API version 2021-03-25, so make sure you're using that version or later. The bug caused it to not always select the upper scope correctly.

The parent operator is really powerful for these kinds of nested queries where you need to filter based on the outer document's values. It keeps everything in a single query without needing to pass variables or make multiple requests.

terminology the word you’re looking for is
join
: https://www.sanity.io/docs/groq-joins and to grab fields from the parent query you can use
^.fieldName
the
^
means use the parent field.
so in yours you’d want
category->title == ^.categoryTitle
or it might be
^.pages.categoryTitle
since its an inner field.
though that might not work. you’d probably have to move the relatedArticles into
pages
so it can reference the individual page category.
because what that original query will return is a list of pages[{},{},{}] so you couldnt reference a single page category. basically this:
{
'pages': query...., {
    'categoryTitle': category-title,
    'relatedArticles': query... category->title == ^.categoryTitle ...
  }
}
Hey Parker, thanks a lot for your help - i had originally used the parent selector for a join, and hadnt got it working. However after looking at your solution, i was able to adjust it to this to get it to work

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?