Query referenced tag title in GROQ array filter

5 replies
Last updated: Aug 1, 2023
Hello DevI only want to get "NextJS" of the title from the reference of the tag in the document of "gorq", how do you guys solve it?

export default defineType({
  name: 'contents',
  title: 'Contents',
  type: 'document',
  fields: [
    defineField({
      name: 'tags',
      title: 'Tags',
      type: 'array',
      of: [{type: 'reference', to: [{type: 'tags'}]}],
    }),
  ],
})

*[_type == "contents" && tags[]-> title == "NextJS" ] {
...
}
AI Update

Looking at your query, you're on the right track! The issue is that when you filter with tags[]-> title == "NextJS", you're checking if any tag matches, but then you need to actually project/return the title in your results.

Here are a few approaches depending on what you want to achieve:

If you want just the matching tag titles:

*[_type == "contents" && "NextJS" in tags[]->title] {
  "matchingTags": tags[]->title
}

If you want only the "NextJS" title specifically:

*[_type == "contents" && "NextJS" in tags[]->title] {
  "nextjsTag": tags[]->{title}[title == "NextJS"][0].title
}

If you want to filter the tags array to only include matching references:

*[_type == "contents" && "NextJS" in tags[]->title] {
  _id,
  "filteredTags": tags[]->{ title }[title == "NextJS"]
}

The key things to understand here:

  1. tags[]->title dereferences all tag references and gets their titles as an array
  2. tags[]->{title} dereferences and projects each tag, giving you more control over filtering
  3. The filter condition checks if the value exists, but you still need to project what you want in the result using projections

The most common pattern for your use case would be:

*[_type == "contents" && "NextJS" in tags[]->title] {
  ...,
  "tagTitles": tags[]->title
}

This gives you all content documents that have a "NextJS" tag, and returns an array of all tag titles (including "NextJS") for each document. The ... spreads all other fields from the content document, while "tagTitles" creates a new field with the dereferenced tag titles.

Show original thread
5 replies
The GROQ looks correct. What issue are you facing and what are the actual and expected results? If you are looking to retrieve only specific values from the result, you can use projections , something like this:
*[_type == "contents" && tags[]->title == "NextJS"] {
 _id,
 title,
 "Titles": tags[]->title,
}
user F

*[_type == "contents" ] {
 tags[]->{
   title
 }
}

**result**
  0:{…} 1 property
  tags:null
  1:{…} 1 property
    tags:[…] 2 items
      0:{…} 1 property
    title:flutter
      1:{…} 1 property
    title:NextJS
  2:{…} 1 property
    tags:null
  3:{…} 1 property
    tags:[…] 2 items
      0:{…} 1 property
        title:zustand
      1:{…} 1 property
        title:NextJS
  4:{…} 1 property
    tags:null
  5:{…} 1 property
    tags:null
If you do this, you'll get it, but if you use the one
user F
did, you won't get it
Try this maybe?
*[_type == "contents" && tags[]->title match "NextJS"] {
 "Titles": tags[]->title,
}
Thanks to you, I solved it! Thank you
user F

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?