A sophisticated visual query builder for Statamic CMS that generates Elasticsearch DSL queries for complex product filtering and search. Built specifically for e-commerce applications using the Rapidez framework.
- Drag & drop interface - Build complex queries without writing code
- Nested group logic - Create groups within groups with AND/OR operators
- Collapsible groups - Manage complex queries with expandable sections
- Visual condition builder - Point-and-click interface for all query operations
- Product attribute integration - Automatically fetches and maps product attributes
- Stock status queries - Built-in support for inventory filtering
- Elasticsearch DSL generation - Converts visual queries to optimized search syntax
- Performance caching - Cached query generation for better performance
- Text fields - String operations (contains, starts with, ends with, etc.)
- Select fields - Single and multi-select with custom options
- Number fields - Numeric comparisons and ranges
- Date fields - Advanced date filtering with relative and absolute dates
- Stock status - Specialized e-commerce inventory filtering
- Relative dates - TODAY, TOMORROW, YESTERDAY
- Dynamic ranges - LAST_X_DAYS, NEXT_X_DAYS with custom offsets
- Period filters - THIS_WEEK, THIS_MONTH, THIS_YEAR
- Manual dates - Custom date picker for specific dates
- Offset calculations - Today ± X days/weeks/months/years
- Query presets - Save and load common filtering scenarios
- Template system - Multiple output formats (slider, listing, etc.)
- Import/export - Share query configurations
- Validation - Automatic validation and correction of imported queries
- Unlimited nesting - Groups within groups with no limits
- Reorderable conditions - Drag conditions and groups to reorder
- Duplicate functionality - Clone groups and conditions
- Conflict resolution - Smart handling of preset merging vs overriding
Install via Composer:
composer require rapidez/statamic-query-builderPublish the configuration and views:
php artisan vendor:publish --provider="Rapidez\StatamicQueryBuilder\ServiceProvider"The addon comes with a pre-configured ProductQueryBuilder fieldtype for immediate use:
# In your blueprint
fields:
product_filter:
type: product_query_builder
display: Product Filter
instructions: Build complex product queries visuallyCreate a custom query builder for your specific needs:
<template>
<query-builder
:fields="groupedFields"
:sort-fields="sortFields"
:default-limit="50"
:show-limit="true"
:builder-templates="templates"
v-model="value"
@input="$emit('input', $event)"
/>
</template>
<script>
import QueryBuilder from './QueryBuilder.vue';
export default {
components: { QueryBuilder },
mixins: [Fieldtype],
data() {
return {
groupedFields: [
{
label: 'Product Attributes',
options: [
{
label: 'Product Name',
value: 'name',
type: 'text'
},
{
label: 'Category',
value: 'category',
type: 'select',
options: [
{ label: 'Electronics', value: 'electronics' },
{ label: 'Clothing', value: 'clothing' }
]
},
{
label: 'Price',
value: 'price',
type: 'number'
},
{
label: 'Created Date',
value: 'created_at',
type: 'date'
}
]
},
{
label: 'Stock Information',
options: [
{
label: 'Stock Status',
value: 'stock_status',
type: 'select',
operators: ['=', '!='],
options: [
{ label: 'In Stock', value: 'in_stock' },
{ label: 'Out of Stock', value: 'out_of_stock' }
]
}
]
}
],
templates: [
{ label: 'Product Slider', value: 'slider' },
{ label: 'Product Grid', value: 'listing' }
]
}
}
}
</script>=- Exactly equals!=- Does not equalLIKE- Contains textNOT LIKE- Does not containSTARTS_WITH- Begins withENDS_WITH- Ends withIS_NULL- Field is emptyIS_NOT_NULL- Field has value
=- Equals selected value!=- Does not equalIN- Is any of (multiple selection)NOT IN- Is none of (multiple selection)IS_NULL- Nothing selectedIS_NOT_NULL- Has selection
=,!=- Equality comparisons>,<,>=,<=- Numeric comparisonsBETWEEN- Value within rangeNOT_BETWEEN- Value outside rangeIS_NULL,IS_NOT_NULL- Empty/has value
=,!=,>,<,>=,<=- Date comparisonsBETWEEN,NOT_BETWEEN- Date rangesLAST_X_DAYS,NEXT_X_DAYS- Relative rangesTHIS_WEEK,THIS_MONTH,THIS_YEAR- Period filtersIS_NULL,IS_NOT_NULL- Date set/not set
The query builder includes sophisticated date handling:
// Simple relative dates
{ type: 'relative', value: 'TODAY' }
{ type: 'relative', value: 'YESTERDAY' }
{ type: 'relative', value: 'TOMORROW' }
// Dynamic relative dates with offsets
{
type: 'relative',
base: 'TODAY',
offset: -7,
unit: 'days'
}{
type: 'manual',
value: '2024-01-15'
}Create reusable query templates:
{
"category": {
"key": "products",
"label": "Product Queries"
},
"presets": [
{
"key": "featured_products",
"name": "Featured Products",
"description": "Products marked as featured",
"query": {
"groups": [
{
"conjunction": "AND",
"conditions": [
{
"attribute": "featured",
"operator": "=",
"value": "1"
}
]
}
],
"globalConjunction": "AND"
}
}
]
}Configure preset files in your config:
// config/rapidez/query-builder.php
return [
'preset_files' => [
'resources/query-presets/products.json',
'resources/query-presets/categories.json',
]
];The query builder generates structured output perfect for Elasticsearch:
{
"groups": [
{
"conjunction": "AND",
"conditions": [
{
"attribute": "attribute.brand",
"operator": "IN",
"value": ["nike", "adidas"]
},
{
"attribute": "price",
"operator": "BETWEEN",
"value": ["100", "500"]
}
]
}
],
"globalConjunction": "AND",
"limit": 50,
"sortField": "created_at",
"sortDirection": "DESC",
"builderTemplate": "listing"
}This gets automatically converted to Elasticsearch DSL:
{
"query": {
"bool": {
"must": [
{
"terms": {
"attribute.brand.keyword": ["nike", "adidas"]
}
},
{
"range": {
"price": {
"gte": 100,
"lte": 500
}
}
}
]
}
},
"size": 50,
"from": 0
}The chosen template is used to render the results of the query. You can include the right template in the blade template of your page builder item:
@include('rapidez-query-builder::templates.'. $product_query_builder->value()['builderTemplate'], $product_query_builder->value())Configure your product attribute model:
// config/rapidez/query-builder.php
return [
'models' => [
'product_attribute' => App\Models\ProductAttribute::class,
]
];The addon automatically maps Elasticsearch field types:
textfields →.keywordfor exact matchesstock_status→in_stockin Elasticsearch- Attribute fields →
attribute.{attribute_code}prefix
- PHP ^8.0
- Laravel ^9.0|^10.0|^11.0
- Statamic ^4.0|^5.0
- Rapidez framework
- Elasticsearch (via Rapidez Laravel Elasticsearch package)
Contributions are welcome! Please see CONTRIBUTING.md for details.
This package is open-sourced software licensed under the MIT license.