How to do free text search in Portable Text field using GROQ?

11 repliesLast updated: Nov 29, 2025

How can I do a free text search in a portable text field? Like, I have a schema
discount
with a portable text field
description
. I want to be able to search
I.e.
*[_type == "discount"] | score(description match $query) | order(_score desc) [ _score > 0 ]
AI Update

Great question! To search within a Portable Text field in GROQ, you need to use the pt::text() function to convert the Portable Text to plain text, then combine it with the match operator and score() function. Here's how to do it:

*[_type == "discount"] 
| score(pt::text(description) match $query) 
| order(_score desc) 
[_score > 0]

Let me break down what's happening here:

If you want to search across multiple fields with different priorities, you can use the boost() function to weight them differently:

*[_type == "discount"] 
| score(
  boost(title match $query, 3),
  boost(pt::text(description) match $query, 1)
) 
| order(_score desc) 
[_score > 0]

This would prioritize matches in the title field 3x higher than matches in the description field, as explained in this example about ordering search results.

The key insight is that you can't directly use match on Portable Text arrays - you need to convert them to plain text first with pt::text(). Before this function existed, developers had to manually traverse the block structure, but now it's built right into GROQ for exactly this kind of use case!

Show original thread
11 replies

Was this answer helpful?

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.

Related contributions