定制 openplain/laravel-lightsearch 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

openplain/laravel-lightsearch

Composer 安装命令:

composer require openplain/laravel-lightsearch

包简介

A lightweight Laravel Scout driver using database-backed search index. Perfect for small to medium datasets (1K-50K records) without external search services.

README 文档

README

Latest Version on Packagist Total Downloads

Fast, database-backed search for Laravel Scout. No external services, no monthly fees, no infrastructure complexity.

Why This Package?

We created LightSearch because most Laravel applications don't need the complexity of external search services like Algolia or Meilisearch. For small to medium datasets, your existing database is perfectly capable of delivering fast, relevant search results.

Our Goal: Make search simple enough for MVPs, powerful enough for production, and cost-effective for bootstrapped projects.

Real-world performance: 2.95ms average search time on 26,000+ records (view benchmark)

Built on Proven Technology

Rather than reinventing the wheel, LightSearch leverages:

  • Laravel Scout - Familiar API that works across all search drivers
  • Inverted Index Pattern - Classic search architecture used by Meilisearch, Algolia, and Typesense
  • Database-Specific Optimizations - PostgreSQL pg_trgm for fuzzy search, MySQL/SQLite optimized queries

Features

  • 🚀 Database-Backed - Uses your existing MySQL, PostgreSQL, or SQLite database
  • 💰 Zero Cost - No external services, no monthly fees
  • Fast Setup - From install to working search in under 5 minutes
  • 🎯 Field Weighting - Boost relevance of important fields (title > content)
  • 🔍 Fuzzy Search - Typo-tolerant search on PostgreSQL with pg_trgm
  • 🌍 Unicode Support - Perfect handling of special characters (ø, á, ñ, etc.)
  • 🔧 Customizable - Stopwords, token length, field weights all configurable
  • 📦 Scout Compatible - Drop-in replacement for Scout drivers
  • 🔑 UUID Support - Works with string primary keys, not just integers

When to Use LightSearch

Perfect for:

  • Small to medium datasets (1K-50K records)
  • Budget-constrained projects
  • MVPs and prototypes
  • Applications already using Laravel Scout
  • Simple hosting environments (no Docker required)

Not Ideal for:

  • Large datasets (>100K records) → use Meilisearch, Algolia, or Typesense
  • Complex multi-language search → use Algolia or Typesense
  • Real-time autocomplete with sub-10ms response times
  • Advanced features like faceted search, geo-search, or AI-powered ranking

Requirements

  • PHP 8.2 or higher
  • Laravel 11 or 12
  • Laravel Scout 10 or higher

Installation

Install the package via Composer:

composer require openplain/laravel-lightsearch

Publish and run migrations:

php artisan vendor:publish --tag=lightsearch-migrations
php artisan migrate

Optionally publish the configuration file:

php artisan vendor:publish --tag=lightsearch-config

Quick Start

1. Configure Scout Driver

Set LightSearch as your Scout driver in .env:

SCOUT_DRIVER=lightsearch

2. Make Your Model Searchable

Add the Searchable trait and define searchable fields:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;

class Post extends Model
{
    use Searchable;

    protected $fillable = ['title', 'excerpt', 'content'];

    public function toSearchableArray(): array
    {
        return [
            'title' => $this->title,
            'excerpt' => $this->excerpt,
            'content' => $this->content,
        ];
    }
}

3. Import Existing Data

Import your existing records into the search index:

php artisan scout:import "App\Models\Post"

For large datasets, use chunking:

php artisan scout:import "App\Models\Post" --chunk=500

4. Start Searching

Use Scout's familiar API to search your models:

// Basic search
$posts = Post::search('laravel')->get();

// Paginated results
$posts = Post::search('laravel')->paginate(15);

// With query constraints
$posts = Post::search('laravel')
    ->where('published', true)
    ->orderBy('created_at', 'desc')
    ->get();

// Fuzzy search (PostgreSQL only)
$posts = Post::search('laravle')->fuzzy(0.3)->get();

Configuration

LightSearch is configured via config/lightsearch.php. All settings are optional with sensible defaults.

Field Weights

Boost relevance of specific fields by giving them higher weights. Fields with higher weights appear multiple times in the index, making matches more significant.

'model_field_weights' => [
    \App\Models\Post::class => [
        'title' => 3,    // Title matches ranked 3x higher
        'excerpt' => 2,  // Excerpt matches ranked 2x higher
        'content' => 1,  // Content has default weight
    ],
],

How it works: A post with "Laravel" in the title gets 3 index entries for "Laravel", while the same word in content gets only 1. This makes title matches score higher in results.

Stopwords

Common words to exclude from the search index. This reduces index size and improves performance.

'stopwords' => [
    'a', 'an', 'and', 'are', 'as', 'at', 'be', 'by', 'for', 'from',
    'has', 'he', 'in', 'is', 'it', 'its', 'of', 'on', 'that', 'the',
    'to', 'was', 'will', 'with', // ... add your own
],

Set to [] to disable stopword filtering.

Minimum Token Length

Minimum character length for a token to be indexed:

'min_token_length' => 2,  // Default: 2 characters

Note: Setting this too high (e.g., 4) prevents searching for short terms like "API" or "PHP".

Database Connection

Override the default database connection:

'connection' => env('LIGHTSEARCH_DB_CONNECTION', null),

Useful if your search index should live on a different database than your application data.

How It Works

LightSearch uses an inverted index pattern (like Meilisearch, Algolia, and Typesense) implemented in your database:

  1. Indexing: Text is tokenized, normalized, and stored with field weights
  2. Search: Queries use prefix matching (or fuzzy matching on PostgreSQL)
  3. Ranking: Results ordered by occurrence count - more matches rank higher

Field weighting example: with title weight 3 and content weight 1, a match in the title counts 3× more than content.

Advanced Features

Fuzzy Search (PostgreSQL)

PostgreSQL users get automatic typo-tolerant search when the pg_trgm extension is enabled. It handles typos, missing accents, and character substitutions.

Enable pg_trgm (one-time setup):

CREATE EXTENSION pg_trgm;

That's it! Fuzzy search is now automatic:

// Automatically finds "Laravel" even with typo
Post::search('laravle')->get();

// Automatically finds "Tórshavn" without accents
Address::search('Torshavn')->get();

Adjust threshold (optional):

Post::search('laravle')->fuzzy(0.5)->get();  // Stricter (default: 0.3)
Post::search('laravle')->fuzzy(0.2)->get();  // Looser

See FUZZY_SEARCH_RESULTS.md for benchmarks.

Performance

Benchmarked with 26,191 addresses featuring special characters (ø, á, ð):

  • Average search time: 2.95ms
  • Dataset: 26,191 records
  • Fuzzy search: ~110ms (PostgreSQL with pg_trgm)

Full benchmark report →

Comparison

Solution Setup Speed Cost Typo Tolerance
LightSearch 5 min ~3ms $0 Yes (PostgreSQL)
Meilisearch 30 min ~1-5ms $0-$$ Yes
Algolia 15 min ~1-3ms $$$ Yes
Typesense 30 min ~1-5ms $0-$ Yes

Limitations

Be aware of these limitations when choosing LightSearch:

  • Prefix matching only - "search" finds "searching" but not "research"
  • No typo tolerance on MySQL/SQLite - Only PostgreSQL with pg_trgm supports fuzzy search
  • Index size growth - ~4 index entries per record with default field weights
  • Not optimized for autocomplete - Better solutions exist for real-time suggestions
  • No faceted search - Can't filter by category/price/etc. in search results
  • Single-language only - No multi-language stemming or morphology

Maintenance

# Re-index after bulk updates
php artisan scout:import "App\Models\Post"

# Clear all index entries
php artisan scout:flush "App\Models\Post"

Models are automatically indexed on create/update/delete.

Testing

composer test
composer pint

Contributing

We welcome contributions! Please see CONTRIBUTING.md for details.

Security

If you discover a security vulnerability, please email security@openplain.dev. All security vulnerabilities will be promptly addressed.

Please do not open public issues for security vulnerabilities.

License

The MIT License (MIT). Please see License File for more information.

Built with ❤️ by Openplain

openplain/laravel-lightsearch 适用场景与选型建议

openplain/laravel-lightsearch 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 286 次下载、GitHub Stars 达 1, 最近一次更新时间为 2025 年 10 月 23 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「database」 「search」 「lightweight」 「laravel」 「index」 「fulltext」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 openplain/laravel-lightsearch 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 openplain/laravel-lightsearch 我们能提供哪些服务?
定制开发 / 二次开发

基于 openplain/laravel-lightsearch 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 286
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 18
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-10-23