How to limit results per type in Sanity query with multiple document types?

5 replies
Last updated: Nov 29, 2025
I have a pretty specific query I’m trying to call, the purpose of this query is to get the 4 most recent “hikes” and the 1 most recent blog “post”. My query looks like this:
*[_type in ["hikes", "post"]]{
  _type == "hikes" => {
    _createdAt,
    body,
    mainImage,
    number,
    people,
    slug,
    title,
    trailHiked -> {
        name,
        difficulty,
        distance,
        rating,
        trailType,
        location
    }
  },
  _type == "post" => {
    title,
    body,
    mainImage
  }
}
I’m currently using
this resource for selecting multiple types in a query, its working so far but how can I specify the 4 most recent hikes (assuming I use
[0…4]
somewhere) and the most recent post (
[0]
?)?
AI Update

The challenge you're facing is that you need different limits for different document types in a single query. Unfortunately, GROQ doesn't allow you to apply different slice operations ([0...4]) to different document types within a single filter like *[_type in ["hikes", "post"]].

The best solution is to use GROQ's array concatenation operator (+) to combine two separate queries with their own limits and ordering:

*[_type == "hikes"] | order(_createdAt desc) [0...4] {
  _createdAt,
  body,
  mainImage,
  number,
  people,
  slug,
  title,
  trailHiked -> {
    name,
    difficulty,
    distance,
    rating,
    trailType,
    location
  }
} + *[_type == "post"] | order(_createdAt desc) [0] {
  title,
  body,
  mainImage
}

The + operator concatenates the results of both queries into a single array. This gives you exactly what you need: the 4 most recent hikes and the 1 most recent post.

Key points:

  • Each query can have its own order() and slice [0...4] or [0]
  • The + operator merges the results into one array
  • You no longer need the conditional projection syntax (_type == "hikes" => {...}) since each query already filters by type
  • Make sure to add | order(_createdAt desc) to each query to get the most recent documents

If you need the results in a specific order (like all hikes first, then the post), the concatenation order controls that. If you want them sorted together by date after merging, you could wrap the whole thing: (*[_type == "hikes"] | order(_createdAt desc) [0...4]{...}) + (*[_type == "post"] | order(_createdAt desc) [0]{...}) | order(_createdAt desc), though this would mix hikes and posts chronologically.

Show original thread
5 replies

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?