ElasticSearch - latin characters
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!
ElasticSearch - latin characters
Laravel framework version: 10.16.1
Aimeos Laravel version: 2023.04.*
PHP Version: 8.2.8
Environment: Linux
Hello,
I have the ai-elastic plugin.
I want to be able to search for products in cyrillic, but also to be able to find them again if the user uses latin characters to write cyrillic. For example the user types "kniga" instead of "книга" in bulgarian.
What's the best way to do this?
Aimeos Laravel version: 2023.04.*
PHP Version: 8.2.8
Environment: Linux
Hello,
I have the ai-elastic plugin.
I want to be able to search for products in cyrillic, but also to be able to find them again if the user uses latin characters to write cyrillic. For example the user types "kniga" instead of "книга" in bulgarian.
What's the best way to do this?
Re: ElasticSearch - latin characters
Don't know if ElasticSearch supports transliteration of characters at all, Solr may be able to do that.
You have to check the ES documentation to see if you find something but in Aimeos it's not available by default.
You have to check the ES documentation to see if you find something but in Aimeos it's not available by default.
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: ElasticSearch - latin characters
I came up with one solution, but your feedback would also be appreciated:
I have overriden this method:
Aimeos\MShop\Index\Manager\Text\Elastic::hydrate()
I have added this line:
$map['content'][] = Str::ascii( $map['name'] );
This adds the title of the product transliterated.
I used the Laravel String helper for the transliteration:
use Illuminate\Support\Str;
For this to work, the products need to be indexed again:
php artisan aimeos:jobs index/rebuild
Please guide me as to how to override this file, because I've currently changed the original.
Should I host my own private version of the package, or is there a proper way to override it?
- What do you think of my solution?
- Is the "fuzziness" of the search affected compared to searching for the original label?
- Is there any better solution than what I've come up with?
I have overriden this method:
Aimeos\MShop\Index\Manager\Text\Elastic::hydrate()
I have added this line:
$map['content'][] = Str::ascii( $map['name'] );
This adds the title of the product transliterated.
I used the Laravel String helper for the transliteration:
use Illuminate\Support\Str;
For this to work, the products need to be indexed again:
php artisan aimeos:jobs index/rebuild
Please guide me as to how to override this file, because I've currently changed the original.
Should I host my own private version of the package, or is there a proper way to override it?
Code: Select all
/**
* Adds more data from the items to the data entries
*
* @param \Aimeos\Map $items Product items implementing \Aimeos\MShop\Product\Item\Iface
* @param \Aimeos\Map $entries Associative list with product IDs as keys and product data as values
* @return \Aimeos\Map Associative list with product IDs as keys and hydrated product data as values
*/
public function hydrate( \Aimeos\Map $items, \Aimeos\Map $entries ) : \Aimeos\Map
{
$config = $this->context()->config();
$types = $config->get( 'mshop/index/manager/text/types' );
$attrTypes = $config->get( 'mshop/index/manager/text/attribute-types', ['variant', 'default'] );
foreach( $items as $idx => $item )
{
$entry = $entries[$idx] ?? [];
foreach( $this->call( 'getTexts', $item, $types, $attrTypes ) as $langId => $map )
{
$url = $map['url'] ?? $item->getName( 'url', $langId );
if( !isset( $map['name'] ) ) {
$map['content'][] = $map['name'] = $item->getLabel();
}
$map['content'][] = Str::ascii( $map['name'] );
$entry['index.text:url(' . $langId . ')'] = $url;
$entry['index.text:name(' . $langId . ')'] = $map['name'];
$entry['index.text:content(' . $langId . ')'] = array_values( array_unique( $map['content'] ) );
}
$entries[$idx] = $entry;
}
foreach( $this->getSubManagers() as $submanager ) {
$entries = $submanager->hydrate( $items, $entries );
}
return $entries;
}
Re: ElasticSearch - latin characters
Extend your new class which contains the hydrate() method from the original Elastic class and configure the name of your new class using:
Code: Select all
mshop/manager/index/text/name = '...'
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: ElasticSearch - latin characters
Thanks, I got it working.
config/shop.php:
/packages/my-extension/src/MShop/Index/Manager/Text:
config/shop.php:
Code: Select all
'mshop' => [
'index' => [
'manager' => [
'text' => [
'name' => 'ElasticCustom',
],
],
],
],
Code: Select all
<?php
namespace Aimeos\MShop\Index\Manager\Text;
class ElasticCustom
extends Elastic
{
/**
* Adds more data from the items to the data entries
*
* @param \Aimeos\Map $items Product items implementing \Aimeos\MShop\Product\Item\Iface
* @param \Aimeos\Map $entries Associative list with product IDs as keys and product data as values
* @return \Aimeos\Map Associative list with product IDs as keys and hydrated product data as values
*/
public function hydrate( \Aimeos\Map $items, \Aimeos\Map $entries ) : \Aimeos\Map
{
$config = $this->context()->config();
$types = $config->get( 'mshop/index/manager/text/types' );
$attrTypes = $config->get( 'mshop/index/manager/text/attribute-types', ['variant', 'default'] );
foreach( $items as $idx => $item )
{
$entry = $entries[$idx] ?? [];
foreach( $this->call( 'getTexts', $item, $types, $attrTypes ) as $langId => $map )
{
$url = $map['url'] ?? $item->getName( 'url', $langId );
if( !isset( $map['name'] ) ) {
$map['content'][] = $map['name'] = $item->getLabel();
}
$map['content'][] = Transliterate::to_ascii( $map['name'], 'bulgarian' );
$entry['index.text:url(' . $langId . ')'] = $url;
$entry['index.text:name(' . $langId . ')'] = $map['name'];
$entry['index.text:content(' . $langId . ')'] = array_values( array_unique( $map['content'] ) );
}
$entries[$idx] = $entry;
}
foreach( $this->getSubManagers() as $submanager ) {
$entries = $submanager->hydrate( $items, $entries );
}
return $entries;
}
}