arthur2weber / query-craft
Craft elegant DSL queries with fluent, Eloquent-inspired syntax for Elasticsearch, MongoDB, and GraphQL. Build powerful search queries with familiar Laravel-like syntax.
Fund package maintenance!
arthur2weber
Requires
- php: ^8.0
This package is auto-updated.
Last update: 2025-08-21 20:55:09 UTC
README
Elegant Elasticsearch DSL Query Builder for PHP
Craft complex Elasticsearch queries with Laravel-inspired fluent syntax. Zero dependencies, maximum productivity.
π Quick Start
composer require arthur2weber/query-craft
<?php use Arthur2weber\QueryCraft\ElasticQuery; // Simple search with filters $query = new ElasticQuery(); $dslQuery = $query ->search('PHP Elasticsearch', ['title^3', 'content']) ->filter('status', 'published') ->range('created_at', 'gte', '2024-01-01') ->sort('_score', 'desc') ->size(10) ->build(); // Ready for Elasticsearch PHP Client $response = $client->search([ 'index' => 'articles', 'body' => $dslQuery ]);
β¨ Why QueryCraft?
- π― Familiar Syntax - Laravel-like methods for instant productivity
- β‘ Zero Dependencies - Pure PHP, no framework requirements
- π§ Complete DSL Support - Full Elasticsearch 7.x+ compatibility
- π Advanced Features - Aggregations, geo-queries, nested objects
- π‘οΈ Developer Experience - Verbose mode, error translation, performance warnings
- π Rich Documentation - 50+ examples and comprehensive guides
- π Eloquent-Friendly - Zero learning curve for Laravel developers
π For Laravel Developers
If you know Eloquent, you already know QueryCraft!
Use the exact same methods you love:
// β Your familiar Eloquent syntax $usersQuery = User::where('status', 'active') ->whereIn('role', ['admin', 'editor']) ->whereBetween('created_at', [$start, $end]) ->orderByDesc('created_at') ->paginate(15) ->toSql(); // β Identical QueryCraft syntax $usersQuery = (new ElasticQuery()) ->where('status', 'active') ->whereIn('role', ['admin', 'editor']) ->whereBetween('created_at', [$start, $end]) ->orderByDesc('created_at') ->paginate(15) ->build();
Everything works exactly as expected:
where()
,whereIn()
,whereNotIn()
,whereBetween()
orderBy()
,orderByDesc()
,latest()
,oldest()
paginate()
,limit()
,offset()
,take()
,skip()
when()
,unless()
- conditional queriescount()
,avg()
,sum()
,max()
,min()
- aggregations
Plus powerful Elasticsearch features:
- Full-text search with
search()
andmatch()
- Geographic queries with
geoDistance()
andgeoBoundingBox()
- Advanced aggregations and faceted search
- Fuzzy search and auto-complete
π₯ Core Features
π Search & Query Methods
// Text search with boost ->search('PHP Laravel', ['title^3', 'content', 'tags^2']) ->match('title', 'Elasticsearch tutorial') ->matchPhrase('content', 'exact phrase search') ->queryString('title:PHP AND status:published') // Term & filters ->filter('status', 'published') ->terms('category', ['php', 'elasticsearch']) ->range('price', 'gte', 100) ->exists('featured_image') // Advanced search ->fuzzy('title', 'elesticsearch', 2) // 2 typos allowed ->wildcard('filename', '*.php') ->regexp('code', '[a-z]+@[a-z]+')
π Aggregations & Analytics
// Terms aggregation (categories) ->aggregation('categories', [ 'terms' => ['field' => 'category.keyword', 'size' => 10] ]) // Date histogram (time series) ->aggregation('monthly_posts', [ 'date_histogram' => [ 'field' => 'created_at', 'calendar_interval' => 'month' ] ]) // Nested aggregations with statistics ->aggregation('categories', [ 'terms' => [ 'field' => 'category.keyword', 'aggs' => [ 'avg_price' => ['avg' => ['field' => 'price']], 'max_views' => ['max' => ['field' => 'views']] ] ] ])
π Geographic Search
// Find restaurants within 5km ->geoDistance('location', '40.7128,-74.0060', '5km') // Bounding box search ->geoBoundingBox('location', [ 'top_left' => '40.8,-74.1', 'bottom_right' => '40.6,-73.9' ]) // Sort by distance ->sort([ '_geo_distance' => [ 'location' => '40.7128,-74.0060', 'order' => 'asc' ] ])
π‘οΈ Developer Experience
// Enable debugging $query->verbose(); // Get detailed logs $logs = $query->getVerboseLog(); // Performance warnings $warnings = $query->getPerformanceWarnings(); // Human-readable error translation $readable = $query->translateError($elasticsearchError);
π Quick Examples
Laravel Migration (Zero Learning Curve!)
// Before (Eloquent) $posts = Post::where('status', 'published') ->whereIn('category', ['tech', 'programming']) ->orderByDesc('created_at') ->paginate(15); // After (QueryCraft) - Identical syntax! $posts = (new ElasticQuery()) ->where('status', 'published') ->whereIn('category', ['tech', 'programming']) ->orderByDesc('created_at') ->paginate(15); // Enhanced with full-text search $posts = (new ElasticQuery()) ->search('Laravel tutorial', ['title^3', 'content']) // β¨ New superpower ->where('status', 'published') ->whereIn('category', ['tech', 'programming']) ->orderByDesc('_score') // β¨ Sort by relevance ->paginate(15);
Basic Search
// Simple product search with filters $query = new ElasticQuery(); $result = $query ->search('iPhone 13', ['title^3', 'description']) ->filter('status', 'active') ->filter('in_stock', true) ->range('price', 'lte', 1000) ->sort(['_score' => 'desc', 'price' => 'asc']) ->size(20) ->build();
E-commerce with Facets
// Product search with category aggregations $query = new ElasticQuery(); $result = $query ->search($searchTerm, ['name^3', 'brand^2', 'description']) ->filter('status', 'active') ->range('price', 'gte', $minPrice) ->aggregation('brands', [ 'terms' => ['field' => 'brand.keyword', 'size' => 10] ]) ->aggregation('categories', [ 'terms' => ['field' => 'category.keyword', 'size' => 5] ]) ->sort('_score', 'desc') ->build();
Geographic Search
// Find nearby restaurants $query = new ElasticQuery(); $result = $query ->match('type', 'restaurant') ->geoDistance('location', '40.7128,-74.0060', '2km') ->filter('rating', '>=', 4.0) ->sort([ '_geo_distance' => [ 'location' => '40.7128,-74.0060', 'order' => 'asc' ] ]) ->build();
π Documentation
- π Complete Wiki - Comprehensive usage guide with examples
- β‘ Quick Reference - All methods and patterns
- π§ Developer Experience - Debugging and optimization
- π Testing Guide - Test suite and quality metrics
- π Test Coverage Summary - Detailed test statistics and coverage
- πΊοΈ Roadmap - Future development plans
π§ͺ Testing
# Quick tests (recommended for development) ./tt # All tests ./tt all # Specific categories ./tt core search filters utilities # Alternative methods php t.php make test
π€ Contributing
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature
- Run tests:
./tt all
- Commit changes:
git commit -m 'Add amazing feature'
- Push to branch:
git push origin feature/amazing-feature
- Open a Pull Request
π License
This project is licensed under the MIT License.
π Links
- GitHub Repository: arthur2weber/query-craft
- Packagist: arthur2weber/query-craft
- Issues: Report bugs or request features
Made with β€οΈ for the PHP community