Add custom sortation to catalog/lists with ElasticSearch
Forum rules
Always add your Laravel, Aimeos and PHP version as well as your environment (Linux/Mac/Win)
Spam and unrelated posts will be removed immediately!
Always add your Laravel, Aimeos and PHP version as well as your environment (Linux/Mac/Win)
Spam and unrelated posts will be removed immediately!
Add custom sortation to catalog/lists with ElasticSearch
Laravel framework version: 10.12.0
Aimeos Laravel version: ~2023.04
PHP Version: 8.2.6
Environment: Linux
Hello,
How can I add custom sort to catalog/lists with es-elastic?
I have added a custom attribute to my products with a decorator:
This is part of the code, which counts how many times a certain product has been ordered.
The attribute is already added as a column to the products table.
I am using this parameter on the product listing page: f_sort=-orders
I have also added this to Aimeos\Controller\Frontend\Product\StandardCustom:
I get this error:
Aimeos Laravel version: ~2023.04
PHP Version: 8.2.6
Environment: Linux
Hello,
How can I add custom sort to catalog/lists with es-elastic?
I have added a custom attribute to my products with a decorator:
Code: Select all
<?php
namespace Aimeos\MShop\Product\Manager\Decorator;
class MyDecorator
extends \Aimeos\MShop\Common\Manager\Decorator\Base
implements \Aimeos\MShop\Common\Manager\Decorator\Iface
{
private $attr = [
'orders' => [
'code' => 'orders',
'internalcode' => 'mpro."orders"',
'label' => 'Number of times this product has been ordered',
'type' => 'integer',
'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_INT,
],
];
public function getSaveAttributes() : array
{
return parent::getSaveAttributes() + $this->createAttributes( $this->attr );
}
public function getSearchAttributes( bool $sub = true ) : array
{
return parent::getSearchAttributes( $sub ) + $this->createAttributes( $this->attr );
}
}
The attribute is already added as a column to the products table.
I am using this parameter on the product listing page: f_sort=-orders
I have also added this to Aimeos\Controller\Frontend\Product\StandardCustom:
Code: Select all
public function sort( string $key = null ) : Iface
{
...
foreach( $list as $sortkey )
{
...
switch( $sortkey )
{
...
case 'orders':
$this->addExpression( $this->filter->sort( $direction, 'orders' ) );
break;
...
}
}
}
Code: Select all
/shop?f_sort=-orders
Invalid name "orders"
#0 /var/www/vhosts/***********/httpdocs/vendor/aimeoscom/ai-elastic/src/Base/Criteria/Elastic.php(163): Aimeos\Base\Criteria\Expression\Sort\Elastic->toSource()
Re: Add custom sortation to catalog/lists with ElasticSearch
Did you configure your decorator for the product manager?
Do you use Elastic as primary product store or only for fast index?
Do you use Elastic as primary product store or only for fast index?
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, give us a star
If you like Aimeos, give us a star
Re: Add custom sortation to catalog/lists with ElasticSearch
This is my Elastic configuration in "shop.php"
Code: Select all
'index' => [
'manager' => [
'name' => 'ElasticIndex',
'attribute' => [
'name' => 'Elastic',
],
'catalog' => [
'name' => 'Elastic',
],
'price' => [
'name' => 'Elastic',
],
'supplier' => [
'name' => 'Elastic',
],
'text' => [
'name' => 'Elastic',
],
],
],
config/mshop/product.php
Code: Select all
<?php
return [
'manager' => [
'name' => 'StandardCustom',
'decorators' => [
'local' => [ 'MyDecorator' ]
],
]
];
Re: Add custom sortation to catalog/lists with ElasticSearch
Yes, but only for the product manager. When the (Elastic) index manager is used by the frontend controller, it doesn't know of any additional search keys available in the product manager. You have to add your decorator to the index manager too.
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, give us a star
If you like Aimeos, give us a star
Re: Add custom sortation to catalog/lists with ElasticSearch
I think I understand what you're talking about.
Testing by removing the key product.ratings from Aimeos\MShop\Product\Manager\Elastic yields the same error.
But it seems logical to me that my existing decorator in my-extension/config/mshop/product.php should be loaded.
Why is the decorator not visible when working with the Elastic product manager?
Testing by removing the key product.ratings from Aimeos\MShop\Product\Manager\Elastic yields the same error.
But it seems logical to me that my existing decorator in my-extension/config/mshop/product.php should be loaded.
Why is the decorator not visible when working with the Elastic product manager?
Code: Select all
return [
'manager' => [
'name' => 'StandardCustom',
'decorators' => [
'local' => [ 'MyDecorator' ]
],
]
];
Re: Add custom sortation to catalog/lists with ElasticSearch
Further testing:
I added this to Aimeos\MShop\Product\Manager\Elastic:
The "Invalid name" error stopped showing up, but now it's not filtering by the number of orders.
I'm sure that there is at least one queried product, which has an order count of 1 in the aimeos index.
The other products are set to 0
What should I do to get this working?
I added this to Aimeos\MShop\Product\Manager\Elastic:
Code: Select all
$searchConfig = [
...
'orders' => array(
'code' => 'orders',
'internalcode' => 'base.product.orders',
'label' => 'Number of orders',
'type' => 'integer',
'internaltype' => 'integer',
'public' => false,
),
...
]
I'm sure that there is at least one queried product, which has an order count of 1 in the aimeos index.
The other products are set to 0
What should I do to get this working?
Re: Add custom sortation to catalog/lists with ElasticSearch
I somewhat got the sorting working, but still have questions.
What is the proper way to override Aimeos\MShop\Product\Manager\Elastic?
I need to add orders in the $searchConfig, but don't want to modify the original class.
It looks like when mshop/index/manager/name = ElasticIndex is set, then you can't set mshop/product/manager/name. I want to set it to ElasticCustom and create a custom Elastic class, where I will extend the original and add the "orders" attribute, overriding the getSearchAttributes() method.
Aimeos\MShop\Product\Manager\Elastic $searchConfig:
I left the decorator Aimeos\MShop\Product\Manager\Decorator\MyDecorator like this.
Otherwise the orders attribute I want to use does not get indexed in ElasticSearch.
The Elastic class is extended in Aimeos\MShop\Product\Manager\ElasticIndex.
I was planning to create an ElasticIndexCustom class, specify that as the name in mshop/index/manager/name = ElasticIndexCustom, then instead of the extended Elastic inside ElasticIndexCustom, extend another custom ElasticCustom class, where I would add my custom $searchConfig, but that solution seems too messy and I will have to override a bunch of the ai-elastic core code when extending the classes.
The end goal is to add a custom sort attribute to products, also to override as little code as possible so its easier to update in the future.
What is the proper way to override Aimeos\MShop\Product\Manager\Elastic?
I need to add orders in the $searchConfig, but don't want to modify the original class.
It looks like when mshop/index/manager/name = ElasticIndex is set, then you can't set mshop/product/manager/name. I want to set it to ElasticCustom and create a custom Elastic class, where I will extend the original and add the "orders" attribute, overriding the getSearchAttributes() method.
Aimeos\MShop\Product\Manager\Elastic $searchConfig:
Code: Select all
'orders' => array(
'code' => 'orders',
'internalcode' => 'base.orders',
'label' => 'Number of times this product has been ordered',
'type' => 'integer',
'internaltype' => 'integer',
'public' => false,
),
Otherwise the orders attribute I want to use does not get indexed in ElasticSearch.
Code: Select all
<?php
namespace Aimeos\MShop\Product\Manager\Decorator;
class MyDecorator
extends \Aimeos\MShop\Common\Manager\Decorator\Base
implements \Aimeos\MShop\Common\Manager\Decorator\Iface
{
private $attr = [
'orders' => [
'code' => 'orders',
'internalcode' => 'mpro."orders"',
'label' => 'Number of times this product has been ordered',
'type' => 'integer',
'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_INT,
],
];
public function getSaveAttributes() : array
{
return parent::getSaveAttributes() + $this->createAttributes( $this->attr );
}
public function getSearchAttributes( bool $sub = true ) : array
{
return parent::getSearchAttributes( $sub ) + $this->createAttributes( $this->attr );
}
}
The Elastic class is extended in Aimeos\MShop\Product\Manager\ElasticIndex.
I was planning to create an ElasticIndexCustom class, specify that as the name in mshop/index/manager/name = ElasticIndexCustom, then instead of the extended Elastic inside ElasticIndexCustom, extend another custom ElasticCustom class, where I would add my custom $searchConfig, but that solution seems too messy and I will have to override a bunch of the ai-elastic core code when extending the classes.
The end goal is to add a custom sort attribute to products, also to override as little code as possible so its easier to update in the future.
Re: Add custom sortation to catalog/lists with ElasticSearch
You should be able to create a decorator similar to your existing one (only the "internalcode" value is different for Elastic) and apply it to the index manager in the ./config/mshop/index.php:
Index manager decorator:
Code: Select all
return [
'manager' => [
'decorators' => [
'local' => [ 'MyDecorator' ]
],
]
];
Code: Select all
<?php
namespace Aimeos\MShop\Index\Manager\Decorator;
class MyDecorator
extends \Aimeos\MShop\Common\Manager\Decorator\Base
implements \Aimeos\MShop\Common\Manager\Decorator\Iface
{
private $attr = [
'orders' => [
'code' => 'orders',
'internalcode' => 'base.product.orders"',
'label' => 'Number of times this product has been ordered',
'type' => 'integer',
'internaltype' => 'integer',
],
];
public function getSaveAttributes() : array
{
return parent::getSaveAttributes() + $this->createAttributes( $this->attr );
}
public function getSearchAttributes( bool $sub = true ) : array
{
return parent::getSearchAttributes( $sub ) + $this->createAttributes( $this->attr );
}
}
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, give us a star
If you like Aimeos, give us a star
Re: Add custom sortation to catalog/lists with ElasticSearch
Thank you, that seems to work.
But when using the ElasticIndex, this config doesn't seem to work:
/mshop/product/manager/name
What is the proper way to override the product manager and add a custom overriden product item class?
The goal is add custom methods to the item class to get and set attributes.
I tried adding this to my decorator, reading from this documentation:
https://aimeos.org/docs/2023.x/models/extend-managers/
I get the following error:
syntax error, unexpected fully qualified name "\Aimeos\MShop\Product\Item\Sta...", expecting "function" or "const"
I have no issues like this when not using the ElasticSearch index.
But when using the ElasticIndex, this config doesn't seem to work:
/mshop/product/manager/name
What is the proper way to override the product manager and add a custom overriden product item class?
The goal is add custom methods to the item class to get and set attributes.
I tried adding this to my decorator, reading from this documentation:
https://aimeos.org/docs/2023.x/models/extend-managers/
Code: Select all
\Aimeos\MShop\Product\Item\Standard::method( 'getMycolumn', function() {
return (int) $this->get( 'mycolumn' );
} );
syntax error, unexpected fully qualified name "\Aimeos\MShop\Product\Item\Sta...", expecting "function" or "const"
I have no issues like this when not using the ElasticSearch index.
Re: Add custom sortation to catalog/lists with ElasticSearch
Can you please post you complete (custom) configuration related to the mshop config key?
You need to add that to your app/Providers/AppServiceProvider.php in the boot() method.kdim95 wrote: ↑19 Jun 2023, 13:54syntax error, unexpected fully qualified name "\Aimeos\MShop\Product\Item\Sta...", expecting "function" or "const"Code: Select all
\Aimeos\MShop\Product\Item\Standard::method( 'getMycolumn', function() { return (int) $this->get( 'mycolumn' ); } );
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, give us a star
If you like Aimeos, give us a star