Exclude fields in GROQ query without fetching them first

5 replies
Last updated: Jul 30, 2021
Is it possible to exlude data in the groq request? Right now I’m doing the following to remove data, but i guess it just gets overwritten and still queries the data in the first place? I need everything except all data from `cmsvisual`:
*[_type == 'projects'] {
  ..., "cmsvisual": ""
}

AI Update

You're correct that your current approach still fetches the cmsvisual data and then overwrites it with an empty string. Unfortunately, GROQ doesn't have a built-in "exclude" or "omit" operator to remove specific fields from a projection when using the spread operator (...).

However, you have a few options depending on your needs:

Option 1: Explicitly List Fields (Most Efficient)

The most efficient approach is to explicitly project only the fields you need instead of using the spread operator:

*[_type == 'projects'] {
  _id,
  _type,
  title,
  description,
  // ... list all fields except cmsvisual
}

This ensures cmsvisual is never fetched from the Content Lake, reducing data transfer and improving performance.

Option 2: Use null to Override (Still Fetches Data)

Your current approach with "cmsvisual": "" does work for removing the field from the response, but as you suspected, the data is still queried. A slight improvement is using null:

*[_type == 'projects'] {
  ...,
  "cmsvisual": null
}

This is slightly more semantic, but still fetches the data before removing it.

Option 3: Filter at the Application Level

If you're using TypeScript and want type safety, you could fetch all fields and filter them in your application code, though this is less efficient than excluding at the query level.

Why No Native Exclude?

As discussed in this blog post about the GROQ ellipsis operator, the spread operator (...) is designed to include all fields with the ability to override specific ones. The evaluation order means ... is always processed first, and subsequent keys can override those values, but there's no mechanism to explicitly exclude fields from the spread.

Bottom line: If performance matters (especially with large fields like images or arrays), explicitly listing the fields you need is the best approach. If you have many fields and only want to exclude one or two, the override approach works but isn't optimal for performance since the data is still fetched from the Content Lake before being removed from the response.

Show original thread
5 replies
Not at the moment. We’ve been thinking about ways to implement it, but for now you’ll have to explicitly name everything you want
its a bit unhandy, as by naming everything i need, if a new object is added to a schema, i need to update all groq request among the whole frontend. So +1 for this feature 🙂
You can, however, use
null
instead of
""
. In JavaScript,
null
and
undefined
both work as an absent value, so
project.cmsvisual
will evaluate to one of those regardless of whether it’s in the object or not.
Thanks! Just out of curiosity, it will still get queried on the api side, which would add time to query duration, right?
Yes, in the sense that the entire document is always fetched from the underlying document storage, then pruned during query execution.

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?