Querying

Full-text search

Each document carries a generated tsvector of its extracted plain text, Portable Text included, and text::match pushes down to a Postgres tsquery.

Search is a Postgres tsvector, generated from each document's extracted plain text — which means Portable Text is flattened into it, so searching finds words inside a rich-text body rather than only in string fields.

groq
*[_type == "docArticle" && [title, summary, body] match $terms]{
  title,
  "category": category->title
}

The planner pushes the match down to a tsquery, and groq-js is still responsible for the final semantics — the same division of labour as everywhere else in the query path.

What works

  • Word and prefix matching, phrases and negation, as the Studio's default search strategy issues them.
  • Searching across Portable Text bodies, not just strings.
  • Combining a search with ordinary filters and projections.

What is partial

Ranking. Postgres ranks by its own text-search scoring, which is not identical to Sanity's, so the order of results for a broad query can differ even when the set matches. For a documentation search that is usually acceptable; for a "did you mean" experience it is not, and that is why the feature is marked partial rather than shipped.