GROQ match operator with slashes in slug patterns not working as expected

3 replies
Last updated: Jun 14, 2023
I tried to use
match
in a GROQ query to get all the slugs that starts with the same path as the current category.
*[slug.current match "/path/something" + "*"]
But this returns some extra documents that has
path and something elsewhere in the slug, like /path/different/something-document. So it seems like the slashes do something magic here, but I can’t find any documentation on it. How can I get the documents that start with this slug?
AI Update

The match operator isn't the right tool for prefix matching! You're experiencing this issue because match is designed for full-text search, not exact pattern matching. It tokenizes both your search term and the field being searched, treating special characters like slashes as word separators.

When you use *[slug.current match "/path/something" + "*"], the match operator breaks your slug into tokens like ['path', 'something'] and matches any document containing those words anywhere in the slug - which is why you're getting /path/different/something-document in your results.

The Solution: Use string::startsWith()

For checking if a slug starts with a specific path, use the GROQ string function string::startsWith():

*[_type == "yourType" && string::startsWith(slug.current, "/path/something")]{
  slug
}

This will only match documents where slug.current literally begins with "/path/something", giving you exact prefix matching without any tokenization.

Why match Doesn't Work Here

As explained in the match operator article, the match operator tokenizes text based on word boundaries and special characters. Characters like /, @, and . are treated as word separators. So /something/path would be indexed as ['something', 'path'], which is why you're getting unexpected matches.

This tokenization behavior makes match great for free-text search (like searching blog post content), but not suitable for exact string operations like prefix matching on structured strings like slugs or paths.

Alternative Approaches

If string::startsWith() doesn't fit your needs, you can also:

  • Use the in operator with path() for more complex path matching patterns, as shown in the GROQ Functions Reference
  • Use string::split() to break apart the slug and compare individual segments
  • Combine multiple conditions with logical operators for more nuanced filtering

The Query Cheat Sheet has more examples of string functions and filtering techniques if you need other string operations.

Show original thread
3 replies
match
is for text, and will do tokenization. These will all evaluate to true:

"/something/path" match "/path/something"
"/something/path" match "something something path"
"/something/path" match "path? something!"
If you want to search by prefix, you should use
string::startsWith()
.
Ah, thanks, I only found the string global function when searching, but I see there is a string functions further down on the page.
In all the times I've seen that document I never noticed the tokenization part. Super cool!

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?