Feature
Wildcard queries
A wildcard query expands a pattern against a segment's term
dictionary and scores every term that matches. It is how you reach prefixes,
suffixes, and infixes that the analyzer does not produce on its own.
{
"query_text": "",
"wildcard": {
"field": "body",
"pattern": "notif*",
"case_insensitive": true
}
}
Pattern syntax
| Token | Meaning | Example |
|---|---|---|
* | Any run of characters, including none | notif* → notify, notification |
? | Exactly one character | gr?y → gray, grey |
| anything else | Matched literally | *breach* → data-breach is not matched; see below |
The pattern is matched against indexed terms, not against raw
field text. Since the analyzer splits on whitespace and trims only leading and
trailing punctuation, a hyphenated string like data-breach is one
term — *breach* matches it, breach alone does not.
Knowing what your tokens actually look like is most of what makes wildcard
queries predictable.
Parameters
- pattern string · required
- The pattern, with
*and?as above. - case_insensitive bool · default true
-
Lowercases both sides before matching. Terms are already lowercased at
index time, so setting this to
falsemakes an uppercase pattern match nothing rather than making matching stricter in a useful way. Leave it at the default unless you know why you are changing it. - field string · required by the schema
-
Must be supplied, but does not currently scope the match — the term
dictionary is per segment, not per field, so expansion considers terms from
every
Textfield.
Scoring
Expansion happens per segment: the pattern is tested against that segment's
terms, and every match becomes a scoring term. A document matching several
expanded terms accumulates score from each, so notif* ranks a
document containing both notify and notification above
one containing only notification.
When wildcard is present it supplies the scoring terms, and
query_text is not used. Send the pattern on its own.
Cost
Expansion is a linear scan of the term dictionary in each surviving segment, and every expanded term then costs a postings read. That makes cost proportional to how many terms match, not to how selective the query feels:
-
notif*on a legal corpus expands to a handful of terms — cheap. -
*a*expands to most of the dictionary — every postings list in the namespace gets read. -
A leading
*defeats nothing structurally here, since the scan is linear either way, but it does tend to expand far wider.
Term-bloom segment pruning does not help a wildcard query: a bloom answers "is this exact term present", and a pattern has no exact term to ask about. A filter alongside the pattern is what restores pruning, because filter blooms are still consulted before the segment opens.
When to reach for something else
If you are using wildcards for prefix autocomplete over a bounded vocabulary,
indexing an explicit prefix field — or a Keyword field you can
range-filter — will beat a pattern scan by a wide margin, and
stays fast as the dictionary grows.