Added support for search with algolia and elasticsearch
This commit is contained in:
parent
b59f6e7264
commit
e5f90b92d0
|
|
@ -6,6 +6,7 @@
|
|||
<a href="https://packagist.org/packages/bagisto/bagisto"><img src="https://poser.pugx.org/bagisto/bagisto/d/total.svg" alt="Total Downloads"></a>
|
||||
<a href="https://packagist.org/packages/bagisto/bagisto"><img src="https://poser.pugx.org/bagisto/bagisto/v/stable.svg" alt="Latest Stable Version"></a>
|
||||
<a href="https://packagist.org/packages/bagisto/bagisto"><img src="https://poser.pugx.org/bagisto/bagisto/license.svg" alt="License"></a>
|
||||
<a href="#backers"><img src="https://github.com/bagisto/bagisto/workflows/CI/badge.svg" alt="Backers on Open Collective"></a>
|
||||
<a href="#backers"><img src="https://opencollective.com/bagisto/backers/badge.svg" alt="Backers on Open Collective"></a>
|
||||
<a href="#sponsors"><img src="https://opencollective.com/bagisto/sponsors/badge.svg" alt="Sponsors on Open Collective"></a>
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@
|
|||
"ext-pdo": "*",
|
||||
"ext-pdo_mysql": "*",
|
||||
"ext-tokenizer": "*",
|
||||
"algolia/algoliasearch-client-php": "^2.2",
|
||||
"astrotomic/laravel-translatable": "^11.0.0",
|
||||
"babenkoivan/elastic-scout-driver": "^1.1",
|
||||
"barryvdh/laravel-debugbar": "^3.1",
|
||||
"barryvdh/laravel-dompdf": "0.8.6",
|
||||
"doctrine/dbal": "2.9.2",
|
||||
|
|
@ -30,6 +32,7 @@
|
|||
"kalnoy/nestedset": "5.0.1",
|
||||
"konekt/concord": "^1.2",
|
||||
"laravel/framework": "^7.0",
|
||||
"laravel/scout": "^8.0",
|
||||
"laravel/socialite": "^4.4",
|
||||
"laravel/tinker": "^2.0",
|
||||
"laravel/ui": "^2.0",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'hosts' => [
|
||||
env('ELASTIC_HOST', 'localhost:9200'),
|
||||
]
|
||||
];
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Search Engine
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option controls the default search connection that gets used while
|
||||
| using Laravel Scout. This connection is used when syncing all models
|
||||
| to the search service. You should adjust this based on your needs.
|
||||
|
|
||||
| Supported: "algolia", "null"
|
||||
|
|
||||
*/
|
||||
|
||||
'driver' => env('SCOUT_DRIVER', 'algolia'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Index Prefix
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify a prefix that will be applied to all search index
|
||||
| names used by Scout. This prefix may be useful if you have multiple
|
||||
| "tenants" or applications sharing the same search infrastructure.
|
||||
|
|
||||
*/
|
||||
|
||||
'prefix' => env('SCOUT_PREFIX', ''),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Queue Data Syncing
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option allows you to control if the operations that sync your data
|
||||
| with your search engines are queued. When this is set to "true" then
|
||||
| all automatic data syncing will get queued for better performance.
|
||||
|
|
||||
*/
|
||||
|
||||
'queue' => env('SCOUT_QUEUE', false),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Chunk Sizes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| These options allow you to control the maximum chunk size when you are
|
||||
| mass importing data into the search engine. This allows you to fine
|
||||
| tune each of these chunk sizes based on the power of the servers.
|
||||
|
|
||||
*/
|
||||
|
||||
'chunk' => [
|
||||
'searchable' => 500,
|
||||
'unsearchable' => 500,
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Soft Deletes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option allows to control whether to keep soft deleted records in
|
||||
| the search indexes. Maintaining soft deleted records can be useful
|
||||
| if your application still needs to search for the records later.
|
||||
|
|
||||
*/
|
||||
|
||||
'soft_delete' => false,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Algolia Configuration
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may configure your Algolia settings. Algolia is a cloud hosted
|
||||
| search engine which works great with Scout out of the box. Just plug
|
||||
| in your application ID and admin API key to get started searching.
|
||||
|
|
||||
*/
|
||||
|
||||
'algolia' => [
|
||||
'id' => env('ALGOLIA_APP_ID', ''),
|
||||
'secret' => env('ALGOLIA_SECRET', ''),
|
||||
],
|
||||
|
||||
];
|
||||
|
|
@ -20,9 +20,27 @@ class Product extends Model implements ProductContract
|
|||
|
||||
protected $typeInstance;
|
||||
|
||||
// protected $with = ['attribute_family', 'inventories'];
|
||||
/**
|
||||
* The "booted" method of the model.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
// protected $table = 'products';
|
||||
static::deleting(function ($product) {
|
||||
foreach ($product->product_flats as $productFlat) {
|
||||
$productFlat->unsearchable();
|
||||
}
|
||||
|
||||
foreach ($product->variants as $variant) {
|
||||
foreach ($variant->product_flats as $productFlat) {
|
||||
$productFlat->unsearchable();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the product attribute family that owns the product.
|
||||
|
|
@ -40,6 +58,14 @@ class Product extends Model implements ProductContract
|
|||
return $this->hasMany(ProductAttributeValueProxy::modelClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the product variants that owns the product.
|
||||
*/
|
||||
public function product_flats()
|
||||
{
|
||||
return $this->hasMany(ProductFlatProxy::modelClass(), 'product_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the product variants that owns the product.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,10 +3,13 @@
|
|||
namespace Webkul\Product\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Laravel\Scout\Searchable;
|
||||
use Webkul\Product\Contracts\ProductFlat as ProductFlatContract;
|
||||
|
||||
class ProductFlat extends Model implements ProductFlatContract
|
||||
{
|
||||
use Searchable;
|
||||
|
||||
protected $table = 'product_flat';
|
||||
|
||||
protected $guarded = [
|
||||
|
|
@ -17,6 +20,16 @@ class ProductFlat extends Model implements ProductFlatContract
|
|||
|
||||
public $timestamps = false;
|
||||
|
||||
/**
|
||||
* Get the index name for the model.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function searchableAs()
|
||||
{
|
||||
return 'products_index';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve type instance
|
||||
*
|
||||
|
|
|
|||
|
|
@ -344,12 +344,44 @@ class ProductRepository extends Repository
|
|||
*/
|
||||
public function searchProductByAttribute($term)
|
||||
{
|
||||
$results = app(ProductFlatRepository::class)->scopeQuery(function($query) use($term) {
|
||||
$channel = request()->get('channel') ?: (core()->getCurrentChannelCode() ?: core()->getDefaultChannelCode());
|
||||
$channel = request()->get('channel') ?: (core()->getCurrentChannelCode() ?: core()->getDefaultChannelCode());
|
||||
|
||||
$locale = request()->get('locale') ?: app()->getLocale();
|
||||
$locale = request()->get('locale') ?: app()->getLocale();
|
||||
|
||||
return $query->distinct()
|
||||
if (config('scout.driver') == 'algolia') {
|
||||
$results = app(ProductFlatRepository::class)->getModel()::search('query', function ($searchDriver, string $query, array $options) use($term, $channel, $locale) {
|
||||
$queries = explode('_', $term);
|
||||
|
||||
$options['similarQuery'] = array_map('trim', $queries);
|
||||
|
||||
$searchDriver->setSettings([
|
||||
'attributesForFaceting' => [
|
||||
"searchable(locale)",
|
||||
"searchable(channel)"
|
||||
]
|
||||
]);
|
||||
|
||||
$options['facetFilters'] = ['locale:' . $locale, 'channel:' . $channel];
|
||||
|
||||
return $searchDriver->search($query, $options);
|
||||
})
|
||||
->where('status', 1)
|
||||
->where('visible_individually', 1)
|
||||
->orderBy('product_id', 'desc')
|
||||
->paginate(16);
|
||||
} else if(config('scout.driver') == 'elastic') {
|
||||
$queries = explode('_', $term);
|
||||
|
||||
$results = app(ProductFlatRepository::class)->getModel()::search(implode(' OR ', $queries))
|
||||
->where('status', 1)
|
||||
->where('visible_individually', 1)
|
||||
->where('channel', $channel)
|
||||
->where('locale', $locale)
|
||||
->orderBy('product_id', 'desc')
|
||||
->paginate(16);
|
||||
} else {
|
||||
$results = app(ProductFlatRepository::class)->scopeQuery(function($query) use($term, $channel, $locale) {
|
||||
return $query->distinct()
|
||||
->addSelect('product_flat.*')
|
||||
->where('product_flat.status', 1)
|
||||
->where('product_flat.visible_individually', 1)
|
||||
|
|
@ -361,11 +393,12 @@ class ProductRepository extends Repository
|
|||
|
||||
foreach (array_map('trim', $queries) as $value) {
|
||||
$subQuery->orWhere('product_flat.name', 'like', '%' . urldecode($value) . '%')
|
||||
->orWhere('product_flat.short_description', 'like', '%' . urldecode($value) . '%');
|
||||
->orWhere('product_flat.short_description', 'like', '%' . urldecode($value) . '%');
|
||||
}
|
||||
})
|
||||
->orderBy('product_id', 'desc');
|
||||
})->paginate(16);
|
||||
})->paginate(16);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue