GROQ match filter not working with periods before wildcard (1.*)

1 replies
Last updated: Feb 19, 2023
Hi, I ran into an issue trying to filter documents with a
match
query. I'm trying to filter on a string field containing version number-like data - 1.2.3. So I though I could get all the "version 1.x"-related documents with
version match '1.*'
but it seems periods before the wildcard -
.*
- for some reason does not work.
version match '1.2.3'
returns documents, but
version match '1.*'
does not.. 😕 I don't see the documentation mentioning
.
being a special character in this context. Is this a bug?
AI Update

This is actually expected behavior, not a bug! The match operator isn't designed for pattern matching with version numbers or structured strings containing periods.

Here's what's happening: The match operator is specifically for full-text search with tokenization. It treats special characters like . as word separators. So when you have version containing "1.2.3", it gets tokenized into separate searchable terms: ['1', '2', '3'].

When you query version match '1.*', the period before the wildcard causes issues because . isn't treated as a literal character - it's a word boundary. That's why version match '1.2.3' works (it matches all three tokens) but version match '1.*' doesn't work as expected.

As the match operator documentation explains, this tokenization is intentional - for example, "banana@sanity.io" gets indexed as ['banana', 'sanity', 'io'].

The solution: For version number filtering, you need to use standard GROQ string comparison instead. Here are a few approaches:

Option 1: Prefix comparison with comparison operators

// Match all versions starting with "1."
*[_type == "yourType" && version >= "1." && version < "2."]

Option 2: Use the in operator with an array

// If you have specific versions you want to match
*[_type == "yourType" && version in ["1.0.0", "1.2.3", "1.5.0"]]

Option 3: String slicing for prefix checking

// Check if first two characters are "1."
*[_type == "yourType" && version[0..2] == "1."]

The key takeaway: match is designed for free-text search scenarios (like searching article content or user-generated text), not for structured string patterns like version numbers, file paths, or IDs. For those use cases, stick with standard string comparison operators (==, >=, <) or string slicing operations.

Show original thread
1 reply
The
match
operator is made for human text, and can't be used this way. A string like
1.2.3
is turned into the tokens
[1, 2, 3]
, and then matched against the text, which is also tokenized this way. So
"1.2.3" match "3.2.1"
returns true.
If you only want to search by prefix, I recommend using
string::startsWith()
, e.g.:
string::startsWith(version, "1.")
This will match
1.2
,
1.2.3
, etc.

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?