elasticsuite icon indicating copy to clipboard operation
elasticsuite copied to clipboard

Ability to force type & indexing analyzer for non-searchable fields

Open scottsb opened this issue 5 years ago • 2 comments

Currently it is possible to set the search analyzer in elasticsuite_indices.xml with the defaultSearchAnalyzer key, but this gets ignored if the field is not used for search or sorting. This has a carryon effect of also overriding our field type specification (gets forced to keyword).

The method getFieldAnalyzers ignores our defaultSearchAnalyzer since our field is not searchable/sortable, forcing the analyzer to UNTOUCHED. Then getPropertyConfig forces the type to keyword based on that.

https://github.com/Smile-SA/elasticsuite/blob/2.10.x/src/module-elasticsuite-core/Index/Mapping/Field.php#L328

Our use case is a whitespace separated list of tokens (stored as a product attribute) that we have to filter all searches by (we have separate custom filters to do this). These tokens should not actually be directly searchable or sortable. Even though we specified the field type as text, because it's forced to keyword, the field is not analyzed, and a match to a single token does not work. Our current planned workaround is to add a plugin to getMappingPropertyConfig() that overrides the return value when it's our field, but that's not as ideal as if we could do it declaratively.

scottsb avatar Feb 26 '21 04:02 scottsb

Hi @scottsb

that's an interesting topic and I think it could improve Elasticsuite.

Since I'm answering with a lot of delay, maybe you implemented by yourself with a plugin in the meantime.

Could you share what you ended up doing ?

Regards

romainruaud avatar Apr 30 '21 07:04 romainruaud

Yes, we wrote a plugin on Smile\ElasticsuiteCore\Index\Mapping\Field. Here's our plugin class, sanitized of our specific proprietary use case:

<?php
namespace Ripen\Example\Plugin;

use Smile\ElasticsuiteCore\Index\Mapping\Field;
use Ripen\Example\Model\Product;

class ForceESFieldProps
{
    /**
     * Workaround for this issue that prevents this from being defined in XML:
     * https://github.com/Smile-SA/elasticsuite/issues/2085
     *
     * @param Field $field
     * @param array $propertyConfig
     * @return array
     */
    public function afterGetMappingPropertyConfig(
        Field $field,
        array $propertyConfig
    ) {
        if (in_array($field->getName(), Product::EXAMPLE_FIELDS)) {
            $propertyConfig['type'] = Field::FIELD_TYPE_TEXT;
            $propertyConfig['analyzer'] = Field::ANALYZER_WHITESPACE;
            unset($propertyConfig['ignore_above']);
        }

        return $propertyConfig;
    }
}

scottsb avatar May 01 '21 16:05 scottsb