Range Query¶
Range queries filter documents based on numeric field values within a specified range.
Basic Usage¶
// Integer range
QueryBuilder.intRangeQuery("pages", 100, 500).buildForageQuery()
// Float range
QueryBuilder.floatRangeQuery("rating", 4.0f, 5.0f).buildForageQuery()
Types¶
Integer Range Query¶
// Books with 200-400 pages
QueryBuilder.intRangeQuery("pages", 200, 400).buildForageQuery()
// Books published after 2020
QueryBuilder.intRangeQuery("year", 2020, Integer.MAX_VALUE).buildForageQuery()
// Books published before 2020
QueryBuilder.intRangeQuery("year", Integer.MIN_VALUE, 2019).buildForageQuery()
Float Range Query¶
// Books rated 4.0 to 5.0
QueryBuilder.floatRangeQuery("rating", 4.0f, 5.0f).buildForageQuery()
// Products under $50
QueryBuilder.floatRangeQuery("price", 0f, 49.99f).buildForageQuery()
// Products $100 and above
QueryBuilder.floatRangeQuery("price", 100f, Float.MAX_VALUE).buildForageQuery()
Range Boundaries¶
Both boundaries are inclusive by default:
// Includes pages=100 and pages=500
QueryBuilder.intRangeQuery("pages", 100, 500)
// Document with pages=100 → ✓ Match
// Document with pages=300 → ✓ Match
// Document with pages=500 → ✓ Match
// Document with pages=501 → ✗ No match
Combined with Other Queries¶
Range as Filter¶
// Search "programming" with rating filter
QueryBuilder.booleanQuery()
.query(QueryBuilder.matchQuery("title", "programming").build())
.query(QueryBuilder.floatRangeQuery("rating", 4.0f, 5.0f).build())
.clauseType(ClauseType.MUST)
.buildForageQuery()
Multiple Range Filters¶
// Books: 200-500 pages, rating 4+, published 2020+
QueryBuilder.booleanQuery()
.query(QueryBuilder.intRangeQuery("pages", 200, 500).build())
.query(QueryBuilder.floatRangeQuery("rating", 4.0f, 5.0f).build())
.query(QueryBuilder.intRangeQuery("year", 2020, 2024).build())
.clauseType(ClauseType.MUST)
.buildForageQuery()
Non-Scoring Filter¶
// Range filter that doesn't affect score
QueryBuilder.booleanQuery()
.query(QueryBuilder.matchQuery("title", "java").build())
.query(QueryBuilder.floatRangeQuery("rating", 4.0f, 5.0f)
.clauseType(ClauseType.FILTER).build())
.clauseType(ClauseType.MUST)
.buildForageQuery()
With Boosting¶
// Boost documents in the "sweet spot" page range
QueryBuilder.booleanQuery()
.query(QueryBuilder.matchQuery("title", "programming").build())
.query(QueryBuilder.intRangeQuery("pages", 200, 400).boost(1.5f).build())
.clauseType(ClauseType.SHOULD)
.buildForageQuery()
Field Requirements¶
Range queries require numeric fields:
// In your document creation
new ForageDocument(book.getId(), Arrays.asList(
new IntField("pages", new int[]{book.getPages()}), // ✓ Range queryable
new IntField("year", new int[]{book.getYear()}), // ✓ Range queryable
new FloatField("rating", new float[]{book.getRating()}), // ✓ Range queryable
new FloatField("price", new float[]{book.getPrice()}) // ✓ Range queryable
));
TextField Not Supported
Range queries don't work on TextField or StringField. Use IntField or FloatField.
Common Use Cases¶
Price Filtering¶
// Products in price range
QueryBuilder.floatRangeQuery("price", minPrice, maxPrice)
Date Range (as Epoch)¶
// Store dates as epoch milliseconds
new IntField("publishedAt", new int[]{(int)(date.toEpochMilli() / 1000)})
// Query recent books (last 30 days)
long thirtyDaysAgo = Instant.now().minus(30, ChronoUnit.DAYS).getEpochSecond();
QueryBuilder.intRangeQuery("publishedAt", (int)thirtyDaysAgo, Integer.MAX_VALUE)
Rating Tiers¶
// Excellent: 4.5+
QueryBuilder.floatRangeQuery("rating", 4.5f, 5.0f)
// Good: 4.0-4.5
QueryBuilder.floatRangeQuery("rating", 4.0f, 4.49f)
// Average: 3.0-4.0
QueryBuilder.floatRangeQuery("rating", 3.0f, 3.99f)
Quantity Filters¶
// In stock (quantity > 0)
QueryBuilder.intRangeQuery("quantity", 1, Integer.MAX_VALUE)
// Low stock (1-5 items)
QueryBuilder.intRangeQuery("quantity", 1, 5)
// Out of stock
QueryBuilder.intRangeQuery("quantity", 0, 0)
Performance¶
Range queries on numeric fields are very efficient due to Lucene's point-based indexing:
| Dataset Size | Typical Query Time |
|---|---|
| 10K docs | < 1ms |
| 100K docs | 1-5ms |
| 1M docs | 5-20ms |
Related Topics¶
- Boolean Query - Combine range with other queries
- Sorting - Sort by numeric fields
- Field Types - Numeric field types