PHPackages                             laravel-global-search/global-search - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Search &amp; Filtering](/categories/search)
4. /
5. laravel-global-search/global-search

ActiveLibrary[Search &amp; Filtering](/categories/search)

laravel-global-search/global-search
===================================

A comprehensive Laravel package for global search functionality with Meilisearch integration, multi-tenancy support, and advanced features.

v1.1.37(7mo ago)058MITPHPPHP ^8.3

Since Sep 24Pushed 7mo agoCompare

[ Source](https://github.com/selimppc/laravel-global-search)[ Packagist](https://packagist.org/packages/laravel-global-search/global-search)[ RSS](/packages/laravel-global-search-global-search/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (11)Versions (21)Used By (0)

Laravel Global Search
=====================

[](#laravel-global-search)

A powerful, fully configurable Laravel package for global search with Meilisearch integration and multi-tenancy support.

> **v1.1.29**: 🚀 **Fully Dynamic &amp; Configurable** - Zero hardcoded values! Every aspect is user-configurable via environment variables.

📖 Documentation
---------------

[](#-documentation)

- **[Configuration Guide](CONFIGURATION.md)** - Complete reference for all 30+ configuration options
- **[Changelog](CHANGELOG.md)** - Version history and upgrade guides

---

🚀 Quick Start
-------------

[](#-quick-start)

### 1. Install

[](#1-install)

```
composer require laravel-global-search/global-search
```

### 2. Configure

[](#2-configure)

```
# Publish config
php artisan vendor:publish --tag=global-search-config

# Add to .env
MEILISEARCH_HOST=http://localhost:7700
MEILISEARCH_KEY=your-master-key
```

### 3. Setup Models

[](#3-setup-models)

Edit `config/global-search.php`:

```
'mappings' => [
    [
        'model' => App\Models\User::class,
        'index' => 'users',
        'primaryKey' => 'id',
        'fields' => ['id', 'name', 'email', 'phone', 'created_at'],
        'filterable' => ['user_type', 'status', 'created_at'],
        'sortable' => ['name', 'created_at', 'updated_at'],
        'computed' => [
            'url' => fn($model) => route('users.show', $model->id),
        ],
    ],
],
```

### 4. Sync Settings &amp; Index

[](#4-sync-settings--index)

```
# Step 1: Sync settings to Meilisearch (REQUIRED for filters/sorting)
php artisan search:sync-settings

# Step 2: Index your data
php artisan search:reindex

# Step 3: Process the queue
php artisan queue:work --stop-when-empty
```

> **⚠️ Important:** Always run `search:sync-settings` **before** indexing when you:
>
> - First set up the package
> - Change filterable/sortable attributes in config
> - Add new indexes or modify index settings
>
> **Without syncing settings, filters and sorting will NOT work!**

```
// Search via API
GET /global-search?q=john&limit=10

// Or use the service
$results = app('global-search')->search('john');
```

---

🎯 Core Features
---------------

[](#-core-features)

- **100% Configurable** - No hardcoded values, all via config/env
- **Multi-Tenancy** - Automatic tenant detection and isolation
- **Dynamic Limits** - Configurable default/max limits
- **Smart Caching** - Configurable TTL and cache drivers
- **Performance Monitoring** - Slow query detection and metrics
- **Advanced Filtering** - Filter by any configured field
- **Sorting** - Multi-field sorting support
- **Job-Based** - All operations use background jobs

---

📊 API Usage
-----------

[](#-api-usage)

### Basic Search

[](#basic-search)

```
GET /global-search?q=john
```

### With Filters

[](#with-filters)

```
GET /global-search?q=john&filters[user_type]=Client&filters[status]=1
```

### With Sorting

[](#with-sorting)

```
GET /global-search?q=john&sort[name]=asc&sort[created_at]=desc
```

### With Limit

[](#with-limit)

```
GET /global-search?q=john&limit=50
```

### Multi-Tenant

[](#multi-tenant)

```
# Automatic detection from subdomain
GET https://tenant1.yourdomain.com/global-search?q=john

# Or specify tenant
GET /global-search?q=john&tenant=tenant1
```

---

🔧 Configuration
---------------

[](#-configuration)

### Essential Settings

[](#essential-settings)

```
# Meilisearch
MEILISEARCH_HOST=http://localhost:7700
MEILISEARCH_KEY=your-master-key

# Limits
GLOBAL_SEARCH_DEFAULT_LIMIT=10
GLOBAL_SEARCH_MAX_LIMIT=100

# Cache
GLOBAL_SEARCH_CACHE_ENABLED=true
GLOBAL_SEARCH_CACHE_TTL=60

# Pipeline
GLOBAL_SEARCH_BATCH_SIZE=1000
GLOBAL_SEARCH_CHUNK_SIZE=100

# Multi-Tenancy
GLOBAL_SEARCH_TENANT_ENABLED=true
```

**See [CONFIGURATION.md](CONFIGURATION.md) for complete options.**

---

🛠️ Commands
-----------

[](#️-commands)

```
# Reindex all data
php artisan search:reindex

# Sync Meilisearch settings
php artisan search:sync-settings

# Check health
php artisan search:health

# View performance metrics
php artisan search:performance

# Flush all indexes
php artisan search:flush
```

---

🏢 Multi-Tenancy
---------------

[](#-multi-tenancy)

Enable in config:

```
'tenant' => [
    'enabled' => true,
    'identifier_column' => 'id',
],
```

Automatic detection from:

- Subdomain: `tenant1.domain.com`
- Header: `X-Tenant-ID: tenant1`
- Query: `?tenant=tenant1`
- Route: `/tenant/{tenant}/...`
- Auth user: `auth()->user()->tenant_id`

---

🔍 Filtering &amp; Sorting
-------------------------

[](#-filtering--sorting)

### Configure in `config/global-search.php`:

[](#configure-in-configglobal-searchphp)

```
'mappings' => [
    [
        'model' => App\Models\Product::class,
        'index' => 'products',
        'filterable' => ['status', 'category', 'price', 'created_at'],
        'sortable' => ['price', 'name', 'created_at'],
    ],
],

'index_settings' => [
    'products' => [
        'filterableAttributes' => ['status', 'category', 'price', 'created_at'],
        'sortableAttributes' => ['price', 'name', 'created_at'],
        'searchableAttributes' => ['name', 'description', 'sku'],
    ],
],
```

### Apply settings:

[](#apply-settings)

```
# Step 1: Sync settings first (REQUIRED!)
php artisan search:sync-settings

# Step 2: Reindex data
php artisan search:reindex

# Step 3: Process queue
php artisan queue:work --stop-when-empty
```

> **💡 Tip:** After changing any filterable/sortable attributes in your config, always run `search:sync-settings` first!

### Use in API:

[](#use-in-api)

```
# Filter
GET /global-search?q=product&filters[status]=active&filters[category]=electronics

# Sort
GET /global-search?q=product&sort[price]=asc&sort[created_at]=desc

# Pagination (offset + limit)
GET /global-search?q=product&limit=20&offset=40

# Combined: Filter + Sort + Pagination
GET /global-search?q=product&filters[status]=active&sort[price]=asc&limit=20&offset=0
```

---

🎨 Data Transformation
---------------------

[](#-data-transformation)

### 1. Automatic (No code needed)

[](#1-automatic-no-code-needed)

```
class User extends Model
{
    // That's it!
}
```

### 2. Model Method

[](#2-model-method)

```
class User extends Model
{
    public function toSearchableArray(): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'full_name' => $this->first_name . ' ' . $this->last_name,
        ];
    }
}
```

### 3. Config-Based

[](#3-config-based)

```
'mappings' => [
    [
        'model' => App\Models\User::class,
        'index' => 'users',
        'fields' => ['id', 'name', 'email'],
        'computed' => [
            'url' => fn($m) => route('users.show', $m->id),
            'full_name' => fn($m) => $m->first_name . ' ' . $m->last_name,
        ],
    ],
],
```

---

🔒 Production Security (IMPORTANT!)
----------------------------------

[](#-production-security-important)

**⚠️ The global search endpoint is PUBLIC by default.** Secure it in production!

### Simple Authentication (Recommended)

[](#simple-authentication-recommended)

Add this to your `routes/api.php`:

```
// Protect the search endpoint with authentication
Route::middleware(['auth:sanctum'])->group(function () {
    Route::get('/global-search', function(Request $request) {
        // Force user's tenant for security
        $tenant = auth()->user()->tenant_id ?? null;

        return app(\LaravelGlobalSearch\GlobalSearch\Http\Controllers\GlobalSearchController::class)(
            $request->merge(['tenant' => $tenant])
        );
    });
});
```

**Usage with token:**

```
curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://api.yourdomain.com/global-search?q=search"
```

### Or Disable in Production

[](#or-disable-in-production)

```
// routes/api.php - Only enable in development
if (!app()->environment('production')) {
    Route::get('/global-search', [GlobalSearchController::class, '__invoke']);
}
```

**💡 For more security options, see [CONFIGURATION.md](CONFIGURATION.md)**

---

⚡ Performance Tuning
--------------------

[](#-performance-tuning)

### High-Volume Apps

[](#high-volume-apps)

```
GLOBAL_SEARCH_BATCH_SIZE=5000
GLOBAL_SEARCH_CHUNK_SIZE=500
GLOBAL_SEARCH_MAX_LIMIT=50
GLOBAL_SEARCH_CACHE_TTL=600
```

### Low-Memory Environments

[](#low-memory-environments)

```
GLOBAL_SEARCH_BATCH_SIZE=100
GLOBAL_SEARCH_CHUNK_SIZE=10
GLOBAL_SEARCH_MAX_RELATIONSHIP_ITEMS=5
```

### Development

[](#development)

```
GLOBAL_SEARCH_CACHE_ENABLED=false
GLOBAL_SEARCH_LOG_SLOW_QUERIES=true
GLOBAL_SEARCH_SLOW_QUERY_THRESHOLD=100
```

---

🔧 Troubleshooting
-----------------

[](#-troubleshooting)

### Issue: No search results

[](#issue-no-search-results)

```
# Fix everything
php artisan search:reindex
php artisan queue:work --stop-when-empty
```

### Issue: Filters not working

[](#issue-filters-not-working)

```
# Sync settings and reindex
php artisan search:sync-settings
php artisan search:reindex
```

### Issue: Slow queries

[](#issue-slow-queries)

```
# Enable monitoring
GLOBAL_SEARCH_LOG_SLOW_QUERIES=true
GLOBAL_SEARCH_SLOW_QUERY_THRESHOLD=500
```

Check logs for slow query warnings.

---

📦 Response Format
-----------------

[](#-response-format)

```
{
  "success": true,
  "data": {
    "hits": [
      {
        "id": "01j2zp7zgf",
        "name": "John Doe",
        "email": "john@example.com",
        "user_type": "Client",
        "url": "/users/01j2zp7zgf",
        "_index": "users"
      }
    ],
    "meta": {
      "total": 1,
      "indexes": ["users"],
      "query": "john",
      "limit": 10,
      "tenant": "tenant1",
      "duration_ms": 45.23
    }
  },
  "meta": {
    "query": "john",
    "limit": 10,
    "tenant": "tenant1",
    "sort": []
  }
}
```

---

📄 License
---------

[](#-license)

MIT License. See [LICENSE](LICENSE) for details.

---

🆘 Support
---------

[](#-support)

- **Configuration**: See [CONFIGURATION.md](CONFIGURATION.md)
- **Changelog**: See [CHANGELOG.md](CHANGELOG.md)
- **Issues**: [GitHub Issues](https://github.com/laravel-global-search/global-search/issues)

---

**Built with ❤️ for Laravel developers who need powerful, flexible search.**

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance65

Regular maintenance activity

Popularity8

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

20

Last Release

214d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/a4429487371badfeeef03e35a3c450a8262cde65131ad481dbe417c5fe56e47b?d=identicon)[selimppc](/maintainers/selimppc)

---

Top Contributors

[![selimppc](https://avatars.githubusercontent.com/u/7763876?v=4)](https://github.com/selimppc "selimppc (1 commits)")

---

Tags

searchmeilisearchlaravelanalyticsmulti-tenantglobal-search

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/laravel-global-search-global-search/health.svg)

```
[![Health](https://phpackages.com/badges/laravel-global-search-global-search/health.svg)](https://phpackages.com/packages/laravel-global-search-global-search)
```

###  Alternatives

[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9682.1M97](/packages/roots-acorn)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k12.1M99](/packages/laravel-pulse)[laravel/scout

Laravel Scout provides a driver based solution to searching your Eloquent models.

1.7k49.4M479](/packages/laravel-scout)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

255.2k](/packages/aedart-athenaeum)[algolia/scout-extended

Scout Extended extends Laravel Scout adding algolia-specific features

4186.3M6](/packages/algolia-scout-extended)[spatie/laravel-health

Monitor the health of a Laravel application

85810.0M83](/packages/spatie-laravel-health)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
