{"id":13669380,"url":"https://github.com/nqxcode/laravel-lucene-search","last_synced_at":"2025-04-27T02:31:13.925Z","repository":{"id":18430506,"uuid":"21615499","full_name":"nqxcode/laravel-lucene-search","owner":"nqxcode","description":"Laravel 4.2, 5.* package for full-text search over Eloquent models based on ZF2 Lucene.","archived":false,"fork":false,"pushed_at":"2020-03-29T07:06:14.000Z","size":4938,"stargazers_count":73,"open_issues_count":5,"forks_count":26,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-02-25T11:22:23.851Z","etag":null,"topics":["eloquent","eloquent-models","fulltext","laravel","lucene","search","zendsearch"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nqxcode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-07-08T14:20:49.000Z","updated_at":"2024-09-02T17:07:20.000Z","dependencies_parsed_at":"2022-09-02T07:02:28.892Z","dependency_job_id":null,"html_url":"https://github.com/nqxcode/laravel-lucene-search","commit_stats":null,"previous_names":[],"tags_count":65,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nqxcode%2Flaravel-lucene-search","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nqxcode%2Flaravel-lucene-search/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nqxcode%2Flaravel-lucene-search/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nqxcode%2Flaravel-lucene-search/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nqxcode","download_url":"https://codeload.github.com/nqxcode/laravel-lucene-search/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251080024,"owners_count":21533040,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["eloquent","eloquent-models","fulltext","laravel","lucene","search","zendsearch"],"created_at":"2024-08-02T08:01:11.535Z","updated_at":"2025-04-27T02:31:13.622Z","avatar_url":"https://github.com/nqxcode.png","language":"PHP","funding_links":[],"categories":["PHP"],"sub_categories":[],"readme":"Laravel 5.5 Lucene search\n==============\n\n[![Latest Stable Version](https://poser.pugx.org/nqxcode/laravel-lucene-search/v/stable.png)](https://packagist.org/packages/nqxcode/laravel-lucene-search)\n[![Latest Unstable Version](https://poser.pugx.org/nqxcode/laravel-lucene-search/v/unstable.png)](https://packagist.org/packages/nqxcode/laravel-lucene-search)\n[![License](https://poser.pugx.org/nqxcode/laravel-lucene-search/license.png)](https://packagist.org/packages/nqxcode/laravel-lucene-search)\n[![Build Status](https://travis-ci.org/nqxcode/laravel-lucene-search.svg?branch=master)](https://travis-ci.org/nqxcode/laravel-lucene-search)\n[![Coverage Status](https://img.shields.io/coveralls/nqxcode/laravel-lucene-search/master.svg?style=flat)](https://coveralls.io/r/nqxcode/laravel-lucene-search?branch=master)\n\nLaravel 5.5 package for full-text search over Eloquent models based on ZendSearch Lucene.\n\n## Installation\n\nRequire this package in your composer.json and run composer update:\n\n```json\n{\n\t\"require\": {\n        \"nqxcode/laravel-lucene-search\": \"2.4.*\"\n\t}\n}\n```\n\nAfter updating composer, add the ServiceProvider to the providers array in `config/app.php`\n\n```php\n'providers' =\u003e [\n\tNqxcode\\LuceneSearch\\ServiceProvider::class,\n],\n```\n\nIf you want to use the facade to search, add this to your facades in `config/app.php`:\n\n```php\n'aliases' =\u003e [\n\t'Search' =\u003e Nqxcode\\LuceneSearch\\Facade::class,\n],\n```\n## Configuration\n\nPublish the config file into your project by running:\n\n```bash\nphp artisan vendor:publish --provider=\"Nqxcode\\LuceneSearch\\ServiceProvider\"\n```\n### Basic\nIn published config file add descriptions for models which need to be indexed, for example:\n\n```php\n'index' =\u003e [\n\n\t// ...\n\n\tnamespace\\FirstModel::class =\u003e [\n\t\t'fields' =\u003e [\n\t\t\t'name', 'full_description', // fields for indexing\n\t\t]\n\t],\n\n\tnamespace\\SecondModel::class =\u003e [\n\t\t'fields' =\u003e [\n\t\t\t'name', 'short_description', // fields for indexing\n\t\t]\n\t],\n\n\tnamespace\\ModelWithCustomPrimaryKey::class =\u003e [\n\t\t// You can also define your primary key (if you use something else than \"id\")\n\t\t'primary_key' =\u003e 'my_custom_field_name',\n\t\t'fields' =\u003e [\n\t\t\t'username', 'short_description', // fields for indexing\n\t\t]\n\t],\n\n\t// ...\n\n],\n\n```\n### Indexing of dynamic fields\nYou can also index values of **optional fields** (dynamic fields). For enable indexing for optional fields:\n\n- In config for each necessary model add following option:\n```php\n        'optional_attributes' =\u003e true\n\n        // or\n\n        'optional_attributes' =\u003e [\n                'accessor' =\u003e 'custom_name' // with specifying of accessor name\n        ]\n```\n- In model add **special accessor**, that returns list of `field-name =\u003e field-value`.\nBy default `getOptionalAttributesAttribute` accessor will be used.\nIn case accessor name specified in config `getCustomNameAttribute` accessor will be used.\n\nExample:\n\nIn config file:\n\n```php\n        namespace\\FirstModel::class =\u003e [\n                'fields' =\u003e [\n                    'name', 'full_description', // fixed fields for indexing\n                ],\n\n                'optional_attributes' =\u003e true //  enable indexing for dynamic fields\n        ],\n```\n\nIn model add following accessor:\n\n```php\n        public function getOptionalAttributesAttribute()\n        {\n                return [\n                        'optional_attribute1' =\u003e 'value1',\n                        'optional_attribute2' =\u003e 'value2',\n                ];\n        }\n```\n### Score Boosting\nSee details on [Apache Lucene - Scoring](https://lucene.apache.org/core/3_5_0/scoring.html#Score%20Boosting).\n\n#### Model level boosting\nThis is **Document level boosting** in terminology of Apache Lucene. By default all models have **boost** value equal to **1**. For change of this behavior customize boost for necessary models as in the following examples.\n\n- In config for each necessary model add following option:\n```php\n        'boost' =\u003e true\n\n        // or\n\n        'boost' =\u003e [\n                'accessor' =\u003e 'custom_name' // with specifying of accessor name\n        ]\n```\nIn model add following accessor:\n\n```php\n        public function getBoostAttribute()\n        {\n                return 0.5; // customize boost value for model\n        }\n```\n- In model add **special accessor**, that returns boost value.\nBy default `getBoostAttribute` accessor will be used.\nIn case accessor name specified in config `getCustomNameAttribute` accessor will be used.\n\nExample:\n\nIn config file:\n\n```php\n        namespace\\FirstModel::class =\u003e [\n                'fields' =\u003e [\n                    'name', 'full_description',\n                ],\n\n                'boost' =\u003e true // enable boosting for model\n        ],\n```\n\nIn model add following accessor:\n\n```php\n        public function getBoostAttribute()\n        {\n                return 0.5; // customize boost value for model\n        }\n```\n\n#### Model's field level boosting\nThis is **Document's Field level boosting** in terminology of Apache Lucene.\nBy default **boost** is set in **1** for each field. For change of this behavior set boost for necessary fields as in the following examples.\n\nIn config file:\n\n```php\n        namespace\\FirstModel::class =\u003e [\n                'fields' =\u003e [\n                    'name', // field with default boost\n                    'full_description' =\u003e ['boost' =\u003e 0.2], // customize boost value\n                ],\n        ],\n```\n\nOr/and in model accessor:\n```php\n        public function getOptionalAttributesAttribute()\n        {\n                return [\n                        'optional_attribute1' =\u003e 'value1', // field with default boost\n                        'optional_attribute2' =\u003e ['boost' =\u003e 0.5, 'value' =\u003e 'value2'], // customize boost value\n                ];\n        }\n```\n\n### Stemming and stopwords\nBy default the following filters are used in search:\n- Stemming filter for **english/russian** words (for reducing words to their root form),\n- Stopword filters for **english/russian** words (for exclude some words from search index).\n\nThis filters can be deleted or replaced with others.\n```php\n\n'analyzer' =\u003e [\n    'filters' =\u003e [\n    \t// Default stemming filter.\n    \tNqxcode\\Stemming\\TokenFilterEnRu::class,\n    ],\n\n    // List of paths to files with stopwords.\n    'stopwords' =\u003e Nqxcode\\LuceneSearch\\Analyzer\\Stopwords\\Files::get(),\n],\n\n```\n\n## Usage\n### Artisan commands\n#### Initialize or rebuild search index\nFor building of search index run:\n\n```bash\nphp artisan search:rebuild --verbose\n```\n#### Clear search index\nFor clearing of search index run:\n\n```bash\nphp artisan search:clear\n```\n#### Filtering of models in search results\nFor filtering of models in search results each model's class can implements `SearchableInterface`.\nFor example:\n\n```php\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Nqxcode\\LuceneSearch\\Model\\SearchableInterface;\n\nclass Dummy extends Model implements SearchableInterface\n{\n        // ...\n\n        /**\n         * Get id list for all searchable models.\n         */\n        public static function searchableIds()\n        {\n            return self::wherePublish(true)-\u003epluck('id');\n        }\n\n        // ...\n}\n\n```\n\n### Partial updating of search index\nFor register of necessary events (save/update/delete) `use Nqxcode\\LuceneSearch\\Model\\SearchTrait` in target model:\n\n```php\n\n    use Illuminate\\Database\\Eloquent\\Model;\n    use Nqxcode\\LuceneSearch\\Model\\SearchableInterface;\n    use Nqxcode\\LuceneSearch\\Model\\SearchTrait;\n\n    class Dummy extends Model implements SearchableInterface\n    {\n        use SearchTrait;\n\n        // ...\n    }\n\n```\n\n### Perform operations without indexing\n\nIf you want to avoid triggering the indexing, wrap necessary operations in the ``withoutSyncingToSearch()`` method on your model:\n\n```php\nProduct::withoutSyncingToSearch(function () {\n    // mass update position for product, e.g.\n    foreach (Product::all() as $i =\u003e $product) {\n        $product-\u003eupdate(['position' =\u003e $i)]);\n    }    \n});\n```\n\n### Query building\nBuild query in several ways:\n\n#### Using constructor:\n\nBy default, queries which will execute search in the **phrase entirely** are created.\n\n##### Simple queries\n```php\n$query = Search::query('clock'); // search by all fields.\n// or\n$query = Search::where('name', 'clock'); // search by 'name' field.\n// or\n$query = Search::query('clock')              // search by all fields with\n\t-\u003ewhere('short_description', 'analog'); // filter by 'short_description' field.\n// or\n$query = Product::search('clock'); // search only in `Product` model by all fields in case when `Product` use `SearchableTrait`.\n```\n##### Advanced queries\n\nFor `query` and `where` methods it is possible to set the following options:\n- **phrase**     - phrase match (boolean, true by default)\n- **proximity**  - value of distance between words (unsigned integer)\n- **fuzzy**      - value of fuzzy (float, 0 ... 1)\n- **required**   - should match (boolean, true by default)\n- **prohibited** - should not match (boolean, false by default)\n\n###### Examples:\n\nFind all models in which any field contains phrase like 'composite one two phrase':\n```php\n$query = Search::query('composite phrase', '*', ['proximity' =\u003e 2]);\n```\nSearch by each word in query:\n```php\n$query = Search::query('composite phrase', '*', ['phrase' =\u003e false]);\n```\n\n#### Using Lucene raw queries:\n```php\n$query = Search::rawQuery('short_description:\"analog\"');\n// or\n$rawQuery = QueryParser::parse('short_description:\"analog\"');\n$query = Search::rawQuery($rawQuery);\n```\n### Getting of results\n\nFor built query are available following actions:\n\n#### Get all found models\n\n```php\n$models = $query-\u003eget();\n```\n\n#### Get count of results\n```php\n$count = $query-\u003ecount();\n```\n\n#### Get limit results with offset\n\n```php\n$models = $query-\u003elimit(5, 10)-\u003eget(); // Limit = 5 and offset = 10\n```\n#### Paginate the found models\n\n```php\n$paginator = $query-\u003epaginate(50);\n```\n### Highlighting of matches\n\nHighlighting of matches is available for any html fragment encoded in **utf-8** and is executed only for the last executed request.\n\n```php\nSearch::find('nearly all words must be highlighted')-\u003eget();\n$highlighted = Search::highlight('all words');\n\n// highlighted html:\n// '\u003cspan class=\"highlight\"\u003eall\u003c/span\u003e \u003cspan class=\"highlight\"\u003ewords\u003c/span\u003e'\n```\n##\n## License\nPackage licenced under the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnqxcode%2Flaravel-lucene-search","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnqxcode%2Flaravel-lucene-search","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnqxcode%2Flaravel-lucene-search/lists"}