Added support for search with algolia and elasticsearch

This commit is contained in:
jitendra 2020-07-02 17:00:21 +05:30
parent b59f6e7264
commit e5f90b92d0
8 changed files with 686 additions and 693 deletions

View File

@ -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>

View File

@ -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",

1189
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
<?php
return [
'hosts' => [
env('ELASTIC_HOST', 'localhost:9200'),
]
];

91
config/scout.php Normal file
View File

@ -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', ''),
],
];

View File

@ -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.
*/

View File

@ -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
*

View File

@ -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;
}