From 6dd6ae59c51129404a2ab6faebe063ac7096c173 Mon Sep 17 00:00:00 2001 From: "Christopher C. Wells" Date: Thu, 4 Mar 2021 21:54:49 -0800 Subject: [PATCH] Use babenkoivan Elasticsearch ecosystem --- .env.example | 4 +- .phpstorm.meta.php | 55 ++ .../IngredientPickerController.php | 25 +- app/Models/Food.php | 22 +- app/Models/Recipe.php | 17 +- composer.json | 3 + composer.lock | 639 ++++++++++++++++-- config/scout.php | 21 +- .../2021_03_04_193043_create_foods_index.php | 40 ++ ...2021_03_04_193706_create_recipes_index.php | 33 + 10 files changed, 776 insertions(+), 83 deletions(-) create mode 100644 elastic/migrations/2021_03_04_193043_create_foods_index.php create mode 100644 elastic/migrations/2021_03_04_193706_create_recipes_index.php diff --git a/.env.example b/.env.example index e9d40e9..593a5a2 100644 --- a/.env.example +++ b/.env.example @@ -15,5 +15,5 @@ QUEUE_CONNECTION=sync SESSION_DRIVER=file SESSION_LIFETIME=120 -SCOUT_DRIVER=tntsearch -TNTSEARCH_FUZZINESS=true +SCOUT_DRIVER=elastic +ELASTIC_HOST=localhost:9200 diff --git a/.phpstorm.meta.php b/.phpstorm.meta.php index 369f55b..a57a43c 100644 --- a/.phpstorm.meta.php +++ b/.phpstorm.meta.php @@ -22,6 +22,11 @@ namespace PHPSTORM_META { 'CloudCreativity\LaravelJsonApi\Services\JsonApiService' => \CloudCreativity\LaravelJsonApi\Services\JsonApiService::class, 'CloudCreativity\LaravelJsonApi\View\Renderer' => \CloudCreativity\LaravelJsonApi\View\Renderer::class, 'Cviebrock\EloquentSluggable\SluggableObserver' => \Cviebrock\EloquentSluggable\SluggableObserver::class, + 'ElasticMigrations\IndexManagerInterface' => \ElasticMigrations\Adapters\IndexManagerAdapter::class, + 'ElasticScoutDriver\Factories\DocumentFactoryInterface' => \ElasticScoutDriver\Factories\DocumentFactory::class, + 'ElasticScoutDriver\Factories\ModelFactoryInterface' => \ElasticScoutDriver\Factories\ModelFactory::class, + 'ElasticScoutDriver\Factories\SearchRequestFactoryInterface' => \ElasticScoutDriver\Factories\SearchRequestFactory::class, + 'Elasticsearch\Client' => \Elasticsearch\Client::class, 'Facade\FlareClient\Flare' => \Facade\FlareClient\Flare::class, 'Facade\IgnitionContracts\SolutionProviderRepository' => \Facade\Ignition\SolutionProviders\SolutionProviderRepository::class, 'Facade\Ignition\DumpRecorder\DumpRecorder' => \Facade\Ignition\DumpRecorder\DumpRecorder::class, @@ -203,6 +208,11 @@ namespace PHPSTORM_META { 'CloudCreativity\LaravelJsonApi\Services\JsonApiService' => \CloudCreativity\LaravelJsonApi\Services\JsonApiService::class, 'CloudCreativity\LaravelJsonApi\View\Renderer' => \CloudCreativity\LaravelJsonApi\View\Renderer::class, 'Cviebrock\EloquentSluggable\SluggableObserver' => \Cviebrock\EloquentSluggable\SluggableObserver::class, + 'ElasticMigrations\IndexManagerInterface' => \ElasticMigrations\Adapters\IndexManagerAdapter::class, + 'ElasticScoutDriver\Factories\DocumentFactoryInterface' => \ElasticScoutDriver\Factories\DocumentFactory::class, + 'ElasticScoutDriver\Factories\ModelFactoryInterface' => \ElasticScoutDriver\Factories\ModelFactory::class, + 'ElasticScoutDriver\Factories\SearchRequestFactoryInterface' => \ElasticScoutDriver\Factories\SearchRequestFactory::class, + 'Elasticsearch\Client' => \Elasticsearch\Client::class, 'Facade\FlareClient\Flare' => \Facade\FlareClient\Flare::class, 'Facade\IgnitionContracts\SolutionProviderRepository' => \Facade\Ignition\SolutionProviders\SolutionProviderRepository::class, 'Facade\Ignition\DumpRecorder\DumpRecorder' => \Facade\Ignition\DumpRecorder\DumpRecorder::class, @@ -384,6 +394,11 @@ namespace PHPSTORM_META { 'CloudCreativity\LaravelJsonApi\Services\JsonApiService' => \CloudCreativity\LaravelJsonApi\Services\JsonApiService::class, 'CloudCreativity\LaravelJsonApi\View\Renderer' => \CloudCreativity\LaravelJsonApi\View\Renderer::class, 'Cviebrock\EloquentSluggable\SluggableObserver' => \Cviebrock\EloquentSluggable\SluggableObserver::class, + 'ElasticMigrations\IndexManagerInterface' => \ElasticMigrations\Adapters\IndexManagerAdapter::class, + 'ElasticScoutDriver\Factories\DocumentFactoryInterface' => \ElasticScoutDriver\Factories\DocumentFactory::class, + 'ElasticScoutDriver\Factories\ModelFactoryInterface' => \ElasticScoutDriver\Factories\ModelFactory::class, + 'ElasticScoutDriver\Factories\SearchRequestFactoryInterface' => \ElasticScoutDriver\Factories\SearchRequestFactory::class, + 'Elasticsearch\Client' => \Elasticsearch\Client::class, 'Facade\FlareClient\Flare' => \Facade\FlareClient\Flare::class, 'Facade\IgnitionContracts\SolutionProviderRepository' => \Facade\Ignition\SolutionProviders\SolutionProviderRepository::class, 'Facade\Ignition\DumpRecorder\DumpRecorder' => \Facade\Ignition\DumpRecorder\DumpRecorder::class, @@ -565,6 +580,11 @@ namespace PHPSTORM_META { 'CloudCreativity\LaravelJsonApi\Services\JsonApiService' => \CloudCreativity\LaravelJsonApi\Services\JsonApiService::class, 'CloudCreativity\LaravelJsonApi\View\Renderer' => \CloudCreativity\LaravelJsonApi\View\Renderer::class, 'Cviebrock\EloquentSluggable\SluggableObserver' => \Cviebrock\EloquentSluggable\SluggableObserver::class, + 'ElasticMigrations\IndexManagerInterface' => \ElasticMigrations\Adapters\IndexManagerAdapter::class, + 'ElasticScoutDriver\Factories\DocumentFactoryInterface' => \ElasticScoutDriver\Factories\DocumentFactory::class, + 'ElasticScoutDriver\Factories\ModelFactoryInterface' => \ElasticScoutDriver\Factories\ModelFactory::class, + 'ElasticScoutDriver\Factories\SearchRequestFactoryInterface' => \ElasticScoutDriver\Factories\SearchRequestFactory::class, + 'Elasticsearch\Client' => \Elasticsearch\Client::class, 'Facade\FlareClient\Flare' => \Facade\FlareClient\Flare::class, 'Facade\IgnitionContracts\SolutionProviderRepository' => \Facade\Ignition\SolutionProviders\SolutionProviderRepository::class, 'Facade\Ignition\DumpRecorder\DumpRecorder' => \Facade\Ignition\DumpRecorder\DumpRecorder::class, @@ -746,6 +766,11 @@ namespace PHPSTORM_META { 'CloudCreativity\LaravelJsonApi\Services\JsonApiService' => \CloudCreativity\LaravelJsonApi\Services\JsonApiService::class, 'CloudCreativity\LaravelJsonApi\View\Renderer' => \CloudCreativity\LaravelJsonApi\View\Renderer::class, 'Cviebrock\EloquentSluggable\SluggableObserver' => \Cviebrock\EloquentSluggable\SluggableObserver::class, + 'ElasticMigrations\IndexManagerInterface' => \ElasticMigrations\Adapters\IndexManagerAdapter::class, + 'ElasticScoutDriver\Factories\DocumentFactoryInterface' => \ElasticScoutDriver\Factories\DocumentFactory::class, + 'ElasticScoutDriver\Factories\ModelFactoryInterface' => \ElasticScoutDriver\Factories\ModelFactory::class, + 'ElasticScoutDriver\Factories\SearchRequestFactoryInterface' => \ElasticScoutDriver\Factories\SearchRequestFactory::class, + 'Elasticsearch\Client' => \Elasticsearch\Client::class, 'Facade\FlareClient\Flare' => \Facade\FlareClient\Flare::class, 'Facade\IgnitionContracts\SolutionProviderRepository' => \Facade\Ignition\SolutionProviders\SolutionProviderRepository::class, 'Facade\Ignition\DumpRecorder\DumpRecorder' => \Facade\Ignition\DumpRecorder\DumpRecorder::class, @@ -927,6 +952,11 @@ namespace PHPSTORM_META { 'CloudCreativity\LaravelJsonApi\Services\JsonApiService' => \CloudCreativity\LaravelJsonApi\Services\JsonApiService::class, 'CloudCreativity\LaravelJsonApi\View\Renderer' => \CloudCreativity\LaravelJsonApi\View\Renderer::class, 'Cviebrock\EloquentSluggable\SluggableObserver' => \Cviebrock\EloquentSluggable\SluggableObserver::class, + 'ElasticMigrations\IndexManagerInterface' => \ElasticMigrations\Adapters\IndexManagerAdapter::class, + 'ElasticScoutDriver\Factories\DocumentFactoryInterface' => \ElasticScoutDriver\Factories\DocumentFactory::class, + 'ElasticScoutDriver\Factories\ModelFactoryInterface' => \ElasticScoutDriver\Factories\ModelFactory::class, + 'ElasticScoutDriver\Factories\SearchRequestFactoryInterface' => \ElasticScoutDriver\Factories\SearchRequestFactory::class, + 'Elasticsearch\Client' => \Elasticsearch\Client::class, 'Facade\FlareClient\Flare' => \Facade\FlareClient\Flare::class, 'Facade\IgnitionContracts\SolutionProviderRepository' => \Facade\Ignition\SolutionProviders\SolutionProviderRepository::class, 'Facade\Ignition\DumpRecorder\DumpRecorder' => \Facade\Ignition\DumpRecorder\DumpRecorder::class, @@ -1108,6 +1138,11 @@ namespace PHPSTORM_META { 'CloudCreativity\LaravelJsonApi\Services\JsonApiService' => \CloudCreativity\LaravelJsonApi\Services\JsonApiService::class, 'CloudCreativity\LaravelJsonApi\View\Renderer' => \CloudCreativity\LaravelJsonApi\View\Renderer::class, 'Cviebrock\EloquentSluggable\SluggableObserver' => \Cviebrock\EloquentSluggable\SluggableObserver::class, + 'ElasticMigrations\IndexManagerInterface' => \ElasticMigrations\Adapters\IndexManagerAdapter::class, + 'ElasticScoutDriver\Factories\DocumentFactoryInterface' => \ElasticScoutDriver\Factories\DocumentFactory::class, + 'ElasticScoutDriver\Factories\ModelFactoryInterface' => \ElasticScoutDriver\Factories\ModelFactory::class, + 'ElasticScoutDriver\Factories\SearchRequestFactoryInterface' => \ElasticScoutDriver\Factories\SearchRequestFactory::class, + 'Elasticsearch\Client' => \Elasticsearch\Client::class, 'Facade\FlareClient\Flare' => \Facade\FlareClient\Flare::class, 'Facade\IgnitionContracts\SolutionProviderRepository' => \Facade\Ignition\SolutionProviders\SolutionProviderRepository::class, 'Facade\Ignition\DumpRecorder\DumpRecorder' => \Facade\Ignition\DumpRecorder\DumpRecorder::class, @@ -1289,6 +1324,11 @@ namespace PHPSTORM_META { 'CloudCreativity\LaravelJsonApi\Services\JsonApiService' => \CloudCreativity\LaravelJsonApi\Services\JsonApiService::class, 'CloudCreativity\LaravelJsonApi\View\Renderer' => \CloudCreativity\LaravelJsonApi\View\Renderer::class, 'Cviebrock\EloquentSluggable\SluggableObserver' => \Cviebrock\EloquentSluggable\SluggableObserver::class, + 'ElasticMigrations\IndexManagerInterface' => \ElasticMigrations\Adapters\IndexManagerAdapter::class, + 'ElasticScoutDriver\Factories\DocumentFactoryInterface' => \ElasticScoutDriver\Factories\DocumentFactory::class, + 'ElasticScoutDriver\Factories\ModelFactoryInterface' => \ElasticScoutDriver\Factories\ModelFactory::class, + 'ElasticScoutDriver\Factories\SearchRequestFactoryInterface' => \ElasticScoutDriver\Factories\SearchRequestFactory::class, + 'Elasticsearch\Client' => \Elasticsearch\Client::class, 'Facade\FlareClient\Flare' => \Facade\FlareClient\Flare::class, 'Facade\IgnitionContracts\SolutionProviderRepository' => \Facade\Ignition\SolutionProviders\SolutionProviderRepository::class, 'Facade\Ignition\DumpRecorder\DumpRecorder' => \Facade\Ignition\DumpRecorder\DumpRecorder::class, @@ -1470,6 +1510,11 @@ namespace PHPSTORM_META { 'CloudCreativity\LaravelJsonApi\Services\JsonApiService' => \CloudCreativity\LaravelJsonApi\Services\JsonApiService::class, 'CloudCreativity\LaravelJsonApi\View\Renderer' => \CloudCreativity\LaravelJsonApi\View\Renderer::class, 'Cviebrock\EloquentSluggable\SluggableObserver' => \Cviebrock\EloquentSluggable\SluggableObserver::class, + 'ElasticMigrations\IndexManagerInterface' => \ElasticMigrations\Adapters\IndexManagerAdapter::class, + 'ElasticScoutDriver\Factories\DocumentFactoryInterface' => \ElasticScoutDriver\Factories\DocumentFactory::class, + 'ElasticScoutDriver\Factories\ModelFactoryInterface' => \ElasticScoutDriver\Factories\ModelFactory::class, + 'ElasticScoutDriver\Factories\SearchRequestFactoryInterface' => \ElasticScoutDriver\Factories\SearchRequestFactory::class, + 'Elasticsearch\Client' => \Elasticsearch\Client::class, 'Facade\FlareClient\Flare' => \Facade\FlareClient\Flare::class, 'Facade\IgnitionContracts\SolutionProviderRepository' => \Facade\Ignition\SolutionProviders\SolutionProviderRepository::class, 'Facade\Ignition\DumpRecorder\DumpRecorder' => \Facade\Ignition\DumpRecorder\DumpRecorder::class, @@ -1651,6 +1696,11 @@ namespace PHPSTORM_META { 'CloudCreativity\LaravelJsonApi\Services\JsonApiService' => \CloudCreativity\LaravelJsonApi\Services\JsonApiService::class, 'CloudCreativity\LaravelJsonApi\View\Renderer' => \CloudCreativity\LaravelJsonApi\View\Renderer::class, 'Cviebrock\EloquentSluggable\SluggableObserver' => \Cviebrock\EloquentSluggable\SluggableObserver::class, + 'ElasticMigrations\IndexManagerInterface' => \ElasticMigrations\Adapters\IndexManagerAdapter::class, + 'ElasticScoutDriver\Factories\DocumentFactoryInterface' => \ElasticScoutDriver\Factories\DocumentFactory::class, + 'ElasticScoutDriver\Factories\ModelFactoryInterface' => \ElasticScoutDriver\Factories\ModelFactory::class, + 'ElasticScoutDriver\Factories\SearchRequestFactoryInterface' => \ElasticScoutDriver\Factories\SearchRequestFactory::class, + 'Elasticsearch\Client' => \Elasticsearch\Client::class, 'Facade\FlareClient\Flare' => \Facade\FlareClient\Flare::class, 'Facade\IgnitionContracts\SolutionProviderRepository' => \Facade\Ignition\SolutionProviders\SolutionProviderRepository::class, 'Facade\Ignition\DumpRecorder\DumpRecorder' => \Facade\Ignition\DumpRecorder\DumpRecorder::class, @@ -1832,6 +1882,11 @@ namespace PHPSTORM_META { 'CloudCreativity\LaravelJsonApi\Services\JsonApiService' => \CloudCreativity\LaravelJsonApi\Services\JsonApiService::class, 'CloudCreativity\LaravelJsonApi\View\Renderer' => \CloudCreativity\LaravelJsonApi\View\Renderer::class, 'Cviebrock\EloquentSluggable\SluggableObserver' => \Cviebrock\EloquentSluggable\SluggableObserver::class, + 'ElasticMigrations\IndexManagerInterface' => \ElasticMigrations\Adapters\IndexManagerAdapter::class, + 'ElasticScoutDriver\Factories\DocumentFactoryInterface' => \ElasticScoutDriver\Factories\DocumentFactory::class, + 'ElasticScoutDriver\Factories\ModelFactoryInterface' => \ElasticScoutDriver\Factories\ModelFactory::class, + 'ElasticScoutDriver\Factories\SearchRequestFactoryInterface' => \ElasticScoutDriver\Factories\SearchRequestFactory::class, + 'Elasticsearch\Client' => \Elasticsearch\Client::class, 'Facade\FlareClient\Flare' => \Facade\FlareClient\Flare::class, 'Facade\IgnitionContracts\SolutionProviderRepository' => \Facade\Ignition\SolutionProviders\SolutionProviderRepository::class, 'Facade\Ignition\DumpRecorder\DumpRecorder' => \Facade\Ignition\DumpRecorder\DumpRecorder::class, diff --git a/app/Http/Controllers/IngredientPickerController.php b/app/Http/Controllers/IngredientPickerController.php index bd46285..8e01704 100644 --- a/app/Http/Controllers/IngredientPickerController.php +++ b/app/Http/Controllers/IngredientPickerController.php @@ -4,6 +4,8 @@ namespace App\Http\Controllers; use App\Models\Food; use App\Models\Recipe; +use ElasticScoutDriverPlus\Builders\MultiMatchQueryBuilder; +use ElasticScoutDriverPlus\Builders\TermsQueryBuilder; use Illuminate\Database\Eloquent\Collection; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -18,8 +20,27 @@ class IngredientPickerController extends Controller $results = new Collection(); $term = $request->query->get('term'); if (!empty($term)) { - $results = $results->merge(Food::search($term)->get()); - $results = $results->merge(Recipe::search($term)->get()); + $results = Food::boolSearch() + ->join(Recipe::class) + + // Attempt to match exact phrase first. + ->should('match_phrase', ['name' => $term]) + + // Attempt multi-match search on all relevant fields with search-as-you-type on name. + ->should((new MultiMatchQueryBuilder()) + ->fields(['name', 'name._2gram', 'name._3gram', 'detail', 'brand', 'source']) + ->query($term) + ->type('bool_prefix') + ->analyzer('whitespace') + ->fuzziness('AUTO')) + + // Attempt to match on any tags in the term. + ->should((new TermsQueryBuilder()) + ->terms('tags', explode(' ', $term))) + + // Get resulting models. + ->execute() + ->models(); } return response()->json($results->values()); } diff --git a/app/Models/Food.php b/app/Models/Food.php index bd6378c..e891746 100644 --- a/app/Models/Food.php +++ b/app/Models/Food.php @@ -6,6 +6,7 @@ use App\Models\Traits\Ingredient; use App\Models\Traits\Journalable; use App\Models\Traits\Sluggable; use App\Support\Number; +use ElasticScoutDriverPlus\QueryDsl; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Laravel\Scout\Searchable; @@ -73,7 +74,13 @@ use Spatie\Tags\HasTags; */ final class Food extends Model { - use HasFactory, HasTags, Ingredient, Journalable, Searchable, Sluggable; + use HasFactory; + use HasTags; + use Ingredient; + use Journalable; + use QueryDsl; + use Searchable; + use Sluggable; /** * @inheritdoc @@ -128,13 +135,20 @@ final class Food extends Model */ public function toSearchableArray(): array { - $this->tags; return [ - 'id' => $this->id, 'name' => $this->name, + 'tags' => $this->tags->pluck('name')->implode(','), 'detail' => $this->detail, 'brand' => $this->brand, - 'tags' => $this->tags->pluck('name'), + 'source' => $this->source, + 'notes' => $this->notes, + 'calories' => $this->calories, + 'cholesterol' => $this->cholesterol, + 'sodium' => $this->sodium, + 'carbohydrates' => $this->carbohydrates, + 'protein' => $this->protein, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, ]; } diff --git a/app/Models/Recipe.php b/app/Models/Recipe.php index 892d893..436df59 100644 --- a/app/Models/Recipe.php +++ b/app/Models/Recipe.php @@ -6,6 +6,7 @@ use App\Models\Traits\HasIngredients; use App\Models\Traits\Ingredient; use App\Models\Traits\Journalable; use App\Models\Traits\Sluggable; +use ElasticScoutDriverPlus\QueryDsl; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -57,7 +58,14 @@ use Spatie\Tags\HasTags; */ final class Recipe extends Model { - use HasFactory, HasIngredients, HasTags, Ingredient, Journalable, Searchable, Sluggable; + use HasFactory; + use HasIngredients; + use HasTags; + use Ingredient; + use Journalable; + use QueryDsl; + use Searchable; + use Sluggable; /** * @inheritdoc @@ -102,12 +110,13 @@ final class Recipe extends Model */ public function toSearchableArray(): array { - $this->tags; return [ - 'id' => $this->id, 'name' => $this->name, + 'tags' => $this->tags->pluck('name')->implode(','), + 'description' => $this->description, 'source' => $this->source, - 'tags' => $this->tags->pluck('name'), + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, ]; } diff --git a/composer.json b/composer.json index 0f45ce9..4f56865 100644 --- a/composer.json +++ b/composer.json @@ -5,6 +5,9 @@ "license": "MPL-2.0", "require": { "php": "^8.0", + "babenkoivan/elastic-migrations": "^1.4", + "babenkoivan/elastic-scout-driver": "^1.3", + "babenkoivan/elastic-scout-driver-plus": "^2.0", "cloudcreativity/laravel-json-api": "^3.2", "cviebrock/eloquent-sluggable": "^8.0", "fideloper/proxy": "^4.4", diff --git a/composer.lock b/composer.lock index 22ad09d..917d801 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f8b6c15824ff4be21313cc1abc4ae9ad", + "content-hash": "3de6fe1cdf3b3dc2e2eafa5756bd52cd", "packages": [ { "name": "asm89/stack-cors", @@ -62,6 +62,367 @@ }, "time": "2020-10-29T16:03:21+00:00" }, + { + "name": "babenkoivan/elastic-adapter", + "version": "v1.13.0", + "source": { + "type": "git", + "url": "https://github.com/babenkoivan/elastic-adapter.git", + "reference": "68e006c893e3fba4594e9788c6cccbe507bd8508" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/babenkoivan/elastic-adapter/zipball/68e006c893e3fba4594e9788c6cccbe507bd8508", + "reference": "68e006c893e3fba4594e9788c6cccbe507bd8508", + "shasum": "" + }, + "require": { + "elasticsearch/elasticsearch": "^7.3", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.16", + "phpstan/phpstan": "^0.12.32", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "ElasticAdapter\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ivan Babenko", + "email": "babenko.i.a@gmail.com" + } + ], + "description": "Adapter for official PHP Elasticsearch client", + "keywords": [ + "adapter", + "client", + "elastic", + "elasticsearch", + "php" + ], + "support": { + "issues": "https://github.com/babenkoivan/elastic-adapter/issues", + "source": "https://github.com/babenkoivan/elastic-adapter/tree/v1.13.0" + }, + "funding": [ + { + "url": "https://www.buymeacoffee.com/ivanbabenko", + "type": "buymeacoffee" + }, + { + "url": "https://paypal.me/babenkoi", + "type": "paypal" + } + ], + "time": "2021-02-16T07:25:59+00:00" + }, + { + "name": "babenkoivan/elastic-client", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/babenkoivan/elastic-client.git", + "reference": "a1e818b444c5e64afd33a578aa4a009c54aff065" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/babenkoivan/elastic-client/zipball/a1e818b444c5e64afd33a578aa4a009c54aff065", + "reference": "a1e818b444c5e64afd33a578aa4a009c54aff065", + "shasum": "" + }, + "require": { + "elasticsearch/elasticsearch": "^7.3", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.16", + "orchestra/testbench": "^6.12", + "phpstan/phpstan": "^0.12.32", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "ElasticClient\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "ElasticClient\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ivan Babenko", + "email": "babenko.i.a@gmail.com" + } + ], + "description": "The official PHP Elasticsearch client integrated with Laravel", + "keywords": [ + "client", + "elastic", + "elasticsearch", + "laravel", + "php" + ], + "support": { + "issues": "https://github.com/babenkoivan/elastic-client/issues", + "source": "https://github.com/babenkoivan/elastic-client/tree/v1.2.0" + }, + "funding": [ + { + "url": "https://www.buymeacoffee.com/ivanbabenko", + "type": "buymeacoffee" + }, + { + "url": "https://paypal.me/babenkoi", + "type": "paypal" + } + ], + "time": "2021-02-16T07:28:08+00:00" + }, + { + "name": "babenkoivan/elastic-migrations", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/babenkoivan/elastic-migrations.git", + "reference": "3e371dc6451751656eb3a0f788389f3c43b89bbb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/babenkoivan/elastic-migrations/zipball/3e371dc6451751656eb3a0f788389f3c43b89bbb", + "reference": "3e371dc6451751656eb3a0f788389f3c43b89bbb", + "shasum": "" + }, + "require": { + "babenkoivan/elastic-adapter": "^1.13", + "babenkoivan/elastic-client": "^1.2", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.16", + "orchestra/testbench": "^6.12", + "phpstan/phpstan": "^0.12.32", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "ElasticMigrations\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "ElasticMigrations\\": "src" + }, + "files": [ + "src/helpers.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ivan Babenko", + "email": "babenko.i.a@gmail.com" + } + ], + "description": "Elasticsearch migrations for Laravel", + "keywords": [ + "elastic", + "elasticsearch", + "laravel", + "migrations", + "php" + ], + "support": { + "issues": "https://github.com/babenkoivan/elastic-migrations/issues", + "source": "https://github.com/babenkoivan/elastic-migrations/tree/v1.4.0" + }, + "funding": [ + { + "url": "https://www.buymeacoffee.com/ivanbabenko", + "type": "buymeacoffee" + }, + { + "url": "https://paypal.me/babenkoi", + "type": "paypal" + } + ], + "time": "2021-02-25T12:10:19+00:00" + }, + { + "name": "babenkoivan/elastic-scout-driver", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/babenkoivan/elastic-scout-driver.git", + "reference": "3bc0105de26664731a9d5e8a145b010eea8fad4a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/babenkoivan/elastic-scout-driver/zipball/3bc0105de26664731a9d5e8a145b010eea8fad4a", + "reference": "3bc0105de26664731a9d5e8a145b010eea8fad4a", + "shasum": "" + }, + "require": { + "babenkoivan/elastic-adapter": "^1.13", + "babenkoivan/elastic-client": "^1.2", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "babenkoivan/elastic-migrations": "^1.4", + "friendsofphp/php-cs-fixer": "^2.16", + "laravel/legacy-factories": "^1.1", + "laravel/scout": "^8.0", + "orchestra/testbench": "^6.12", + "phpstan/phpstan": "^0.12.32", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "ElasticScoutDriver\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "ElasticScoutDriver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ivan Babenko", + "email": "babenko.i.a@gmail.com" + } + ], + "description": "Elasticsearch driver for Laravel Scout", + "keywords": [ + "driver", + "elastic", + "elasticsearch", + "laravel", + "php", + "scout" + ], + "support": { + "issues": "https://github.com/babenkoivan/elastic-scout-driver/issues", + "source": "https://github.com/babenkoivan/elastic-scout-driver/tree/v1.3.0" + }, + "funding": [ + { + "url": "https://www.buymeacoffee.com/ivanbabenko", + "type": "buymeacoffee" + }, + { + "url": "https://paypal.me/babenkoi", + "type": "paypal" + } + ], + "time": "2021-02-25T12:18:25+00:00" + }, + { + "name": "babenkoivan/elastic-scout-driver-plus", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/babenkoivan/elastic-scout-driver-plus.git", + "reference": "c1f013eacb21c89442e1d103ff889ba30472a9a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/babenkoivan/elastic-scout-driver-plus/zipball/c1f013eacb21c89442e1d103ff889ba30472a9a1", + "reference": "c1f013eacb21c89442e1d103ff889ba30472a9a1", + "shasum": "" + }, + "require": { + "babenkoivan/elastic-adapter": "^1.13", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "babenkoivan/elastic-migrations": "^1.4", + "babenkoivan/elastic-scout-driver": "^1.3", + "friendsofphp/php-cs-fixer": "^2.16", + "laravel/legacy-factories": "^1.1", + "laravel/scout": "^8.0", + "orchestra/testbench": "^6.12", + "phpstan/phpstan": "^0.12.32", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "ElasticScoutDriverPlus\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "ElasticScoutDriverPlus\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ivan Babenko", + "email": "babenko.i.a@gmail.com" + } + ], + "description": "Extension for Elastic Scout Driver", + "keywords": [ + "driver", + "elastic", + "elasticsearch", + "laravel", + "php", + "scout" + ], + "support": { + "issues": "https://github.com/babenkoivan/elastic-scout-driver-plus/issues", + "source": "https://github.com/babenkoivan/elastic-scout-driver-plus/tree/v2.0.0" + }, + "funding": [ + { + "url": "https://www.buymeacoffee.com/ivanbabenko", + "type": "buymeacoffee" + }, + { + "url": "https://paypal.me/babenkoi", + "type": "paypal" + } + ], + "time": "2021-03-01T17:57:56+00:00" + }, { "name": "brick/math", "version": "0.9.1", @@ -691,6 +1052,182 @@ ], "time": "2020-12-29T14:50:06+00:00" }, + { + "name": "elasticsearch/elasticsearch", + "version": "v7.11.0", + "source": { + "type": "git", + "url": "https://github.com/elastic/elasticsearch-php.git", + "reference": "277cd5e182827c59c23e146a836a30470c0f879d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/elastic/elasticsearch-php/zipball/277cd5e182827c59c23e146a836a30470c0f879d", + "reference": "277cd5e182827c59c23e146a836a30470c0f879d", + "shasum": "" + }, + "require": { + "ext-json": ">=1.3.7", + "ezimuel/ringphp": "^1.1.2", + "php": "^7.1 || ^8.0", + "psr/log": "~1.0" + }, + "require-dev": { + "cpliakas/git-wrapper": "~2.0 || ~3.0", + "doctrine/inflector": "^1.3", + "ext-yaml": "*", + "ext-zip": "*", + "mockery/mockery": "^1.2", + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "squizlabs/php_codesniffer": "^3.4", + "symfony/finder": "~4.0", + "symfony/yaml": "~4.0" + }, + "suggest": { + "ext-curl": "*", + "monolog/monolog": "Allows for client-level logging and tracing" + }, + "type": "library", + "autoload": { + "files": [ + "src/autoload.php" + ], + "psr-4": { + "Elasticsearch\\": "src/Elasticsearch/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Zachary Tong" + }, + { + "name": "Enrico Zimuel" + } + ], + "description": "PHP Client for Elasticsearch", + "keywords": [ + "client", + "elasticsearch", + "search" + ], + "support": { + "issues": "https://github.com/elastic/elasticsearch-php/issues", + "source": "https://github.com/elastic/elasticsearch-php/tree/v7.11.0" + }, + "time": "2021-02-11T11:04:51+00:00" + }, + { + "name": "ezimuel/guzzlestreams", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/ezimuel/guzzlestreams.git", + "reference": "abe3791d231167f14eb80d413420d1eab91163a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ezimuel/guzzlestreams/zipball/abe3791d231167f14eb80d413420d1eab91163a8", + "reference": "abe3791d231167f14eb80d413420d1eab91163a8", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Stream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Fork of guzzle/streams (abandoned) to be used with elasticsearch-php", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "Guzzle", + "stream" + ], + "support": { + "source": "https://github.com/ezimuel/guzzlestreams/tree/3.0.1" + }, + "time": "2020-02-14T23:11:50+00:00" + }, + { + "name": "ezimuel/ringphp", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/ezimuel/ringphp.git", + "reference": "0b78f89d8e0bb9e380046c31adfa40347e9f663b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ezimuel/ringphp/zipball/0b78f89d8e0bb9e380046c31adfa40347e9f663b", + "reference": "0b78f89d8e0bb9e380046c31adfa40347e9f663b", + "shasum": "" + }, + "require": { + "ezimuel/guzzlestreams": "^3.0.1", + "php": ">=5.4.0", + "react/promise": "~2.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "ext-curl": "Guzzle will use specific adapters if cURL is present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Ring\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Fork of guzzle/RingPHP (abandoned) to be used with elasticsearch-php", + "support": { + "source": "https://github.com/ezimuel/ringphp/tree/1.1.2" + }, + "time": "2020-02-14T23:51:21+00:00" + }, { "name": "fideloper/proxy", "version": "4.4.1", @@ -2940,6 +3477,56 @@ ], "time": "2020-08-18T17:17:46+00:00" }, + { + "name": "react/promise", + "version": "v2.8.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "f3cff96a19736714524ca0dd1d4130de73dbbbc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/f3cff96a19736714524ca0dd1d4130de73dbbbc4", + "reference": "f3cff96a19736714524ca0dd1d4130de73dbbbc4", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.0 || ^6.5 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "keywords": [ + "promise", + "promises" + ], + "support": { + "issues": "https://github.com/reactphp/promise/issues", + "source": "https://github.com/reactphp/promise/tree/v2.8.0" + }, + "time": "2020-05-12T15:16:56+00:00" + }, { "name": "spatie/eloquent-sortable", "version": "3.11.0", @@ -8611,56 +9198,6 @@ ], "time": "2020-12-04T05:05:53+00:00" }, - { - "name": "react/promise", - "version": "v2.8.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/promise.git", - "reference": "f3cff96a19736714524ca0dd1d4130de73dbbbc4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/promise/zipball/f3cff96a19736714524ca0dd1d4130de73dbbbc4", - "reference": "f3cff96a19736714524ca0dd1d4130de73dbbbc4", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^7.0 || ^6.5 || ^5.7 || ^4.8.36" - }, - "type": "library", - "autoload": { - "psr-4": { - "React\\Promise\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com" - } - ], - "description": "A lightweight implementation of CommonJS Promises/A for PHP", - "keywords": [ - "promise", - "promises" - ], - "support": { - "issues": "https://github.com/reactphp/promise/issues", - "source": "https://github.com/reactphp/promise/tree/v2.8.0" - }, - "time": "2020-05-12T15:16:56+00:00" - }, { "name": "sebastian/cli-parser", "version": "1.0.1", diff --git a/config/scout.php b/config/scout.php index 742fcb9..d698a2e 100644 --- a/config/scout.php +++ b/config/scout.php @@ -15,7 +15,7 @@ return [ | */ - 'driver' => env('SCOUT_DRIVER', 'tntsearch'), + 'driver' => env('SCOUT_DRIVER', 'elastic'), /* |-------------------------------------------------------------------------- @@ -116,23 +116,4 @@ return [ 'secret' => env('ALGOLIA_SECRET', ''), ], - /* - |-------------------------------------------------------------------------- - | TNT Search Configuration - |-------------------------------------------------------------------------- - */ - - 'tntsearch' => [ - 'storage' => storage_path() . '/indexes', - 'fuzziness' => env('TNTSEARCH_FUZZINESS', false), - 'fuzzy' => [ - 'prefix_length' => 2, - 'max_expansions' => 50, - 'distance' => 2 - ], - 'asYouType' => true, - 'searchBoolean' => env('TNTSEARCH_BOOLEAN', false), - 'maxDocs' => env('TNTSEARCH_MAX_DOCS', 500), - ], - ]; diff --git a/elastic/migrations/2021_03_04_193043_create_foods_index.php b/elastic/migrations/2021_03_04_193043_create_foods_index.php new file mode 100644 index 0000000..939f481 --- /dev/null +++ b/elastic/migrations/2021_03_04_193043_create_foods_index.php @@ -0,0 +1,40 @@ +searchAsYouType('name', ['boost' => 2]) + ->keyword('tags', ['normalizer' => 'lowercase']) + ->text('detail', ['boost' => 1.5]) + ->text('brand') + ->text('source') + ->text('notes') + ->float('calories') + ->float('cholesterol') + ->float('sodium') + ->float('carbohydrates') + ->float('protein') + ->date('created_at') + ->date('updated_at'); + }); + } + + /** + * Reverse the migration. + */ + public function down(): void + { + Index::dropIfExists('foods'); + } +} diff --git a/elastic/migrations/2021_03_04_193706_create_recipes_index.php b/elastic/migrations/2021_03_04_193706_create_recipes_index.php new file mode 100644 index 0000000..0b5a276 --- /dev/null +++ b/elastic/migrations/2021_03_04_193706_create_recipes_index.php @@ -0,0 +1,33 @@ +searchAsYouType('name', ['boost' => 2]) + ->keyword('tags', ['normalizer' => 'lowercase']) + ->text('description') + ->text('source') + ->date('created_at') + ->date('updated_at'); + }); + } + + /** + * Reverse the migration. + */ + public function down(): void + { + Index::dropIfExists('recipes'); + } +}