2016-09-17 6 views

Odpowiedz

1

Laravel Scout nie obsługuje zaawansowanych funkcji Elasticsearch. Skończyło się na tym, że trzymałem się Scouta za tworzenie indeksu i aktualizację na podstawie zdarzeń modelu, ale przełączyłem moje wyszukiwanie, aby bezpośrednio korzystać z biblioteki ElasticSearch.

3

W rzeczywistości można to w prosty sposób wykonać za pomocą niestandardowego silnika Scout Engine.

Nazwijmy go ElasticqueryEngine, na przykład, i przedłużyć go z domyślnego ElasticsearchEngine:

<?php 

namespace App\Libs\Scout\Engines; 

use Laravel\Scout\Builder; 
use Laravel\Scout\Engines\ElasticsearchEngine; 

class ElasticqueryEngine extends ElasticsearchEngine 
{ 
    /** 
    * Perform the given search on the engine. 
    * 
    * @param Builder $query 
    * @param array $options 
    * @return mixed 
    */ 
    protected function performSearch(Builder $query, array $options = []) 
    { 
     if (!is_array($query->query)) { 
      return parent::performSearch($query, $options); 
     } 

     $searchQuery = [ 
      'index' => $this->index, 
      'type' => $query->model->searchableAs(), 
      'body' => [ 
       'query' => $query->query, 
      ], 
     ]; 

     if (array_key_exists('size', $options)) { 
      $searchQuery = array_merge($searchQuery, [ 
       'size' => $options['size'], 
      ]); 
     } 
     if (array_key_exists('from', $options)) { 
      $searchQuery = array_merge($searchQuery, [ 
       'from' => $options['from'], 
      ]); 
     } 
     return $this->elasticsearch->search($searchQuery); 
    } 
} 

Dodaj usługodawcą, aby zarejestrować nową ElasticqueryEngine (lub zrobić to w żadnej z istniejących usługodawców):

<?php 

namespace App\Providers; 

use Laravel\Scout\EngineManager; 
use Illuminate\Support\ServiceProvider; 
use Elasticsearch\ClientBuilder as Elasticsearch; 
use App\Libs\Scout\Engines\ElasticqueryEngine; 

class ElasticqueryServiceProvider extends ServiceProvider 
{ 
    /** 
    * Perform post-registration booting of services. 
    * 
    * @return void 
    */ 
    public function boot() 
    { 
     resolve(EngineManager::class)->extend('elasticquery', function() { 
      return new ElasticqueryEngine(
       Elasticsearch::fromConfig(config('scout.elasticsearch.config')), 
       config('scout.elasticsearch.index') 
      ); 
     }); 
    } 

    /** 
    * Register bindings in the container. 
    * 
    * @return void 
    */ 
    public function register() 
    { 
     // 
    } 
} 

nie zapomnij dodać nowego usługodawcę w config/app.php:

'providers' => [ 
    // ... 
    Laravel\Scout\ScoutServiceProvider::class, 
    App\Providers\ElasticqueryServiceProvider::class, 
], 

I zmień sterownik na "elasticquery" w config/scout.php lub .env (SCOUT_DRIVER = elasticquery)

Po tym wszystkim, można wyszukiwać według wszelkich zapytań z https://www.elastic.co/guide/en/elasticsearch/reference/current/full-text-queries.html:

$query = [ 
    'simple_query_string' => [ 
     'query' => 'findme', 
     'fields' => [ 
      'title^5', 
      'description', 
     ], 
    ], 
]; 
$posts = Posts::search($query)->get(); 

// also you can use default ElasticsearchEngine query 
$posts = Posts::search('findme')->where('user_id', 1)->get(); 
+0

lubię tego rozwiązania, ale na razie po prostu wysyłam zapytanie do ElasticSearch bezpośrednio przez pakiet SDK ES PHP. – ATLChris