Filtering arrays in a query and using match for comparison in Sanity.io.

5 replies
Last updated: Nov 11, 2023
Hi all, how can I filter out an array returned from a query?I have a query similar to this one

*[_type == 'movie']{..., actors}
where actors is an array of objects containing the role (
leading
,
support
, etc) and the reference to the actor. I need to filter out the actors array to only include ones in a leading role.
AI Update

You can filter arrays directly within a GROQ projection using bracket notation with a filter condition. For your case with actors and roles, here's how to do it:

*[_type == 'movie']{
  ..., 
  "leadingActors": actors[role == "leading"]
}

The key is placing the filter condition [role == "leading"] directly on the array within your projection. This filters the actors array to only include objects where role equals "leading".

Here are more examples showing different filtering scenarios:

// Filter and project specific fields from the filtered array
*[_type == 'movie']{
  title,
  "leadingActors": actors[role == "leading"]{
    name,
    role
  }
}

// Filter with multiple conditions
*[_type == 'movie']{
  "topActors": actors[role == "leading" && experience > 10]
}

// Filter and follow references in the array
*[_type == 'movie']{
  "leadActors": actors[role == "leading"].person->{
    name,
    bio
  }
}

// Using match for text filtering
*[_type == 'movie']{
  castMembers[characterName match 'Ripley']{
    characterName, 
    person
  }
}

This is documented in the GROQ Query Cheat Sheet under "Object Projections" - specifically the "Filter embedded objects" example. The filter is applied during projection, so it's efficient and only returns the subset of array elements that match your condition.

It sounds like you’ll be able to use the array filter syntax for this:

*[_type == 'movie']{
  ...,
  actors[leading == true], // or maybe...
  // actors[role == 'leading'],
}
Thanks, I don't know what I was doing wrong but I couldn't get it to work as I wanted... But hey, it works now ✌️
And if I wanted all artists named "James" it would be something like this right?

*[_type == 'movie']{
  actors[actor->name == 'James'],
}
Assuming
actors
has this shape:
actors: [
  {
    role: string,
    actor: reference,
  },
  // ...
]
Yes, if the
name
property is literally just James, then that should work. If it’s their full name or you want to do basic matching, you may want to consider using match rather than
==
.
Yup, I'm familiar with it. In this case it would be a full comparison rather than a partial match. Thanks again!

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?