Smile-SA / elasticsuite

Smile ElasticSuite - Magento 2 merchandising and search engine built on ElasticSearch
https://elasticsuite.io
Open Software License 3.0
762 stars 339 forks source link

Cannot override field mapping properties from a custom module #1380

Closed real34 closed 5 years ago

real34 commented 5 years ago

Preconditions

Magento Version : 2.3.0 and 2.3.1

ElasticSuite Version : 2.7.6

Environment : I tried with both

Steps to reproduce

  1. create a new module with the following sequence:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Acme_Integration" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Catalog"/>
            <module name="Smile_ElasticsuiteCatalog"/>
        </sequence>
    </module>
</config>
  1. create an elasticsuite_indices.xml file in this new module, with the following content:
<?xml version="1.0"?>
<indices xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Smile_ElasticsuiteCore:etc/elasticsuite_indices.xsd">

  <index identifier="catalog_product" defaultSearchType="product">
    <type name="product" idFieldName="entity_id">
      <mapping>
        <!-- Working -->
        <field name="category.anothername" type="text" nestedPath="category">
          <isSearchable>1</isSearchable>
          <isUsedInSpellcheck>1</isUsedInSpellcheck>
          <isFilterable>1</isFilterable>
        </field>

        <!-- NOT working -->
        <field name="category.name" type="text" nestedPath="category">
          <isSearchable>1</isSearchable>
          <isUsedInSpellcheck>1</isUsedInSpellcheck>
          <isFilterable>1</isFilterable>
        </field>
      </mapping>
    </type>
  </index>

</indices>
  1. reindex ./bin/magento cache:flush && ./bin/magento index:reindex

Expected result

I would like to customize the metadata for the category.name field, to change https://github.com/Smile-SA/elasticsuite/blob/10e30ee0c4cf0b6734e162dbc1795b384f8210cb/src/module-elasticsuite-catalog/etc/elasticsuite_indices.xml#L68 to 1

  1. the metadata for the category.name field mapping should be:
"name": {
  "copy_to": [ "search", "spelling" ],
  "analyzer": "standard",
  "type": "text",
  "fields": {
    "untouched": {
      "type": "keyword"
    }
  }
},

Actual result

  1. the metadata has not changed, and are:
"name": {
  "copy_to": [ "search", "spelling" ],
  "analyzer": "standard",
  "type": "text"
},
  1. the metadata for the new category.anothername is correct though… so it may be related to XML configuration merging.
real34 commented 5 years ago

For information, it seems indeed to be a limitation of the format used (if I understand correctly). It struggled to find more information about the merging syntax…

We would need additional ids in https://github.com/Smile-SA/elasticsuite/blob/10e30ee0c4cf0b6734e162dbc1795b384f8210cb/src/module-elasticsuite-core/Index/Indices/Config/Reader.php#L48 (I haven’t found a test case in https://github.com/magento/magento2/blob/2.3-develop/lib/internal/Magento/Framework/Config/Test/Unit/DomTest.php that illustrate merging by tag name).

Do you think the only solution would be to add something like <property type="isFilterable">1</property>?

romainruaud commented 5 years ago

On my dev environment, the merge appears to be correct.

I have a module ( I did testing directly in another module I have) which is having this module.xml :

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Smile_ElasticsuiteRating" setup_version="1.2.0">
        <sequence>
            <module name="Smile_ElasticsuiteCore" />
            <module name="Smile_ElasticsuiteVirtualCategory" />
            <module name="Magento_Search" />
            <module name="Magento_Catalog" />
            <module name="Magento_CatalogSearch" />
            <module name="Magento_LayeredNavigation" />
            <module name="Magento_Review" />
        </sequence>
    </module>
</config>

And this elasticsuite_indices.xml :

    <index identifier="catalog_product" defaultSearchType="product">
        <type name="product" idFieldName="entity_id">
            <datasources>
                <datasource name="rating">Smile\ElasticsuiteRating\Model\Product\Indexer\Fulltext\Datasource\RatingData</datasource>
            </datasources>
            <mapping>
                <field name="ratings_summary" type="double"/>
                <field name="category.name" type="text" nestedPath="category">
                    <isSearchable>1</isSearchable>
                    <isUsedInSpellcheck>1</isUsedInSpellcheck>
                    <isFilterable>1</isFilterable>
                </field>
            </mapping>
        </type>
    </index>

So it's quite close to your example imho.

If I log $typeConfigData at this exact line (https://github.com/Smile-SA/elasticsuite/blob/2.7.x/src/module-elasticsuite-core/Index/Indices/Config.php#L121), I have :

...
                    [category.name] => Array
                        (
                            [type] => text
                            [nestedPath] => category
                            [fieldConfig] => Array
                                (
                                    [is_searchable] => 1
                                    [is_used_in_spellcheck] => 1
                                    [is_filterable] => 1
                                )

                        )

...

And my mapping is then :

"name": {
                "type": "text",
                "fields": {
                  "untouched": {
                    "type": "keyword"
                  }
                },
                "copy_to": [
                  "search",
                  "spelling"
                ],
                "analyzer": "standard"
              },
real34 commented 5 years ago

Thanks for your answer. I finally could dig deeper… and found my mistake. It was a PEBCAK… :disappointed: everything I wrote above is incorrect.

TL;DR: The following XML works perfectly on 2.3.1:

<?xml version="1.0"?>
<indices xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Smile_ElasticsuiteCore:etc/elasticsuite_indices.xsd">

    <index identifier="catalog_product" defaultSearchType="product">
        <type name="product" idFieldName="entity_id">
            <mapping>
                <field name="category.name" type="text" nestedPath="category">
                    <isSearchable>1</isSearchable>
                    <isUsedInSpellcheck>1</isUsedInSpellcheck>
                    <isFilterable>1</isFilterable>
                </field>
            </mapping>
        </type>
    </index>

</indices>

Sorry for this false alert, and thanks again for your time! You may update the labels to "question" since it was not a bug in the end.

Here is what happened if interested (`3615 MYLIFE`) I tried on 2.3.1 using a clean setup, and our own composer meta-module for Front-Commerce related code. To do this change, I created a new `FrontCommerce_ElasticSuite` module where I added the XML file. To use my local code, I tried for the first time [Composer’s path repository type](https://getcomposer.org/doc/05-repositories.md#path) **but** there are some weird things regarding `composer.lock` updates when doing this. My `FrontCommerce\ElasticSuite` PSR-4 path (and `registration.php`) was not added to the autoloader, thus my `module:enable --all` did not activate the module without me noticing! [A good read to dive into Composer’s alternatives and local module development](https://github.com/composer/composer/issues/601) In the end, after some composer voodoo, I managed to have a correct lockfile, enable the module and make this mapping change work!