Skip to content

Query Syntax

Foundatio.Lucene supports the full Lucene query syntax. This page documents all supported syntax elements.

Terms

Simple terms search for exact matches:

hello

Wildcards

Use * for multiple characters and ? for single characters:

hello*      // Matches: hello, helloworld, hello123
hel?o       // Matches: hello, helpo, helao
*world      // Matches: world, helloworld (leading wildcard)

WARNING

Leading wildcards (*world) can be expensive. Use QueryValidationOptions.AllowLeadingWildcards = false to disable them.

Phrases

Use quotes for exact phrase matching:

"hello world"

Add ~N to find words within N positions of each other:

"hello world"~2    // "hello" and "world" within 2 words of each other

Field Queries

Specify which field to search:

title:hello
user.name:john       // Nested field
status:active

Default Field

Terms without a field prefix search the default field (or all fields depending on configuration):

hello                // Searches default field(s)
title:hello          // Searches only "title" field

Ranges

Inclusive Ranges

Use square brackets for inclusive ranges (includes boundaries):

price:[100 TO 500]           // 100 <= price <= 500
date:[2020-01-01 TO 2020-12-31]

Exclusive Ranges

Use curly braces for exclusive ranges (excludes boundaries):

price:{100 TO 500}           // 100 < price < 500

Mixed Ranges

Mix inclusive and exclusive boundaries:

price:[100 TO 500}           // 100 <= price < 500
price:{100 TO 500]           // 100 < price <= 500

Open-Ended Ranges

Use * for unbounded ranges:

price:[100 TO *]             // price >= 100
price:[* TO 500]             // price <= 500
age:{18 TO *}                // age > 18

Boolean Operators

AND

Both terms must match:

title:hello AND status:active
title:hello && status:active   // Alternative syntax

OR

Either term must match:

status:active OR status:pending
status:active || status:pending  // Alternative syntax

NOT

Exclude matches:

status:active NOT archived:true
status:active !archived:true     // Alternative syntax

Prefix Operators

Use + (must match) and - (must not match):

+status:active              // Must match
-archived:true              // Must not match
+title:hello -status:draft  // Must match title, must not be draft

Grouping

Use parentheses to group clauses:

(status:active OR status:pending) AND priority:high
title:(hello OR goodbye)

Special Queries

Exists / Missing

Check if a field exists or is missing:

_exists_:email           // Documents with email field
_missing_:phone          // Documents without phone field

Match All

Match all documents:

*:*

Regular Expressions

Use forward slashes for regex patterns:

/joh?n(athan)?/          // Matches: john, jon, jonathan, jonatan
name:/[a-z]+/

TIP

Regex patterns follow the .NET Regex syntax.

Date Math

Elasticsearch-style date math is supported for date fields:

Relative Dates

created:now              // Current time
created:now-1d           // 1 day ago
created:now+1h           // 1 hour from now
created:now-1w           // 1 week ago

Date Math Units

UnitDescription
yYear
MMonth
wWeek
dDay
hHour
mMinute
sSecond

Anchored Date Math

Start from a specific date:

2024-01-01||+1M          // January 1st 2024 plus one month
2024-01-01||+1M/d        // Same, rounded to day

Rounding

Use / to round to a time unit:

now/d                    // Round to start of current day
now/M                    // Round to start of current month
now-1d/d                 // Start of yesterday

Includes

Reference saved or named queries:

@include:savedQuery
@include:my-filter

INFO

Include expansion requires configuring an IncludeResolver function.

Escaping Special Characters

Escape special characters with backslash:

title:hello\:world       // Searches for "hello:world" in title
name:John\ Doe           // Searches for "John Doe"

Special characters that need escaping: + - && || ! ( ) { } [ ] ^ " ~ * ? : \ /

Query Examples

Here are some real-world query examples:

category:electronics AND price:[100 TO 500] AND brand:(apple OR samsung) AND _exists_:inStock

Log Analysis

level:error AND timestamp:[now-1h TO now] AND (service:api OR service:web) NOT test:true
name:john* AND role:(admin OR moderator) AND status:active AND lastLogin:[now-30d TO *]
"annual report" AND year:2024 AND department:(finance OR legal) -draft:true

AST Node Types

When parsing, queries are converted to these AST node types:

Node TypeDescriptionExample
QueryDocumentRoot node-
TermNodeSimple termhello
PhraseNodeQuoted phrase"hello world"
FieldQueryNodeField:value pairtitle:test
RangeNodeRange query[1 TO 10]
BooleanQueryNodeBoolean combinationa AND b
GroupNodeParenthetical group(a OR b)
NotNodeNegation wrapperNOT a
ExistsNode_exists_:field check_exists_:email
MissingNode_missing_:field check_missing_:phone
MatchAllNode*:* match all*:*
RegexNodeRegular expression/pattern/
MultiTermNodeMultiple terms without operatorshello world

Next Steps

Released under the Apache 2.0 License.