is it possible to filter child elements in a query? e.g. in the query below I’d like to return only documents where `deleted != true` ```*[_type == "event"] { _id,...

8 replies
Last updated: Jan 4, 2021
is it possible to filter child elements in a query? e.g. in the query below I’d like to return only documents where
deleted != true

*[_type == "event"] {
      _id,
      _key,
      documents[] -> {
        ...
      }
    } 
AI Update

Yes, it is possible to filter child elements in a GROQ query! You can use a filter inside the array projection to only include documents that meet your criteria.

For your example where you want to return only documents where deleted != true, you can do this:

*[_type == "event"] {
  _id,
  _key,
  documents[deleted != true] -> {
    ...
  }
}

The key is placing the filter [deleted != true] directly after the documents array field and before the dereferencing operator ->.

How it works

When you use square brackets [] after an array field, you're telling GROQ to traverse the array. By adding a filter expression inside those brackets, you filter which elements from the array should be included before dereferencing them.

More examples

You can use various filter conditions:

// Filter by a specific value
documents[status == "active"] -> { ... }

// Filter by existence of a field
documents[defined(publishedAt)] -> { ... }

// Combine multiple conditions
documents[deleted != true && status == "published"] -> { ... }

// Filter by array membership
documents[category in ["news", "blog"]] -> { ... }

Important note

The blank filter [] is required when working with arrays of references. As mentioned in the Sanity documentation on expanding array references, you must use square brackets to traverse the array before dereferencing, so adding your filter condition inside those brackets is the natural way to filter the results.

Is
documents
 an array of references in this case?
yes
user Y
Then
*[_type == "event"] {
      _id,
      _key,
      documents[]->[deleted != true]{
        ...
      }
    }
should work, but will return
documents: []
 where no documents match the filter criteria
works like a charm, much appreciated
user Y
If you want to return nothing, this might work:
*[_type == "event"]{
  _id,
  _key, // there shouldn't be a _key in a document?
  "documents": 
  	select(
    	count(
      	documents[]->[deleted != true]
	  	) > 0 => documents[]->[deleted != true]{...}
	)
}

empty array is totally fine in this case but cool to see these advanced queries! is there any expanded query cheatsheet where these advanced usage examples might live?
Not at the moment, so you'll have to dig in the reference docs to find it 🙂 We totally should build out the cheatsheet though
definitely! it’s already great but there’s so much more to be done with sanity. i’m sure it would save you a lot of time too 😏

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?