Magento 2: what is the search_engine.xml? How to declare a new search engine?

I have checked the file and I could only find it in the release candidates of Magento 2.1.0 (and thus in the develop branch). It is not present in earlier versions.

It was announced that Magento 2.1.0 would include Elasticsearch. I assume, looking at the structure of the XML, that the Elasticsearch module will also include a search_engine.xml exposing <engine name="elasticsearch"> to the system as an engine. I could not yet find anything like that in the release candidates. Also I could not find a file like this in the Magento Solr module. Also I could not find the XSD file search_engine.xsd.

If I look in the Magento Admin, I can configure the Catalog Search engine and choose between MySQL and Solr, but this is coming from a DI configuration and not from the search_engine.xml.

Probably Magento is rewriting this part with the introduction of Elasticsearch. I would think that this is really work in progress or not yet made publicly available, except for this one file, maybe accidentally?


How is that file exactly being used in Magento 2?

If I trace back the usage of the engines configuration in this file, I end up in Magento\Search\Model\SearchEngine\Config. Its interface is

interface ConfigInterface
{
    /**
     * Search engine feature: synonyms
     */
    const SEARCH_ENGINE_FEATURE_SYNONYMS = 'synonyms';

    /**
     * Get declared features of a search engine
     *
     * @param string $searchEngine
     * @return string[]
     */
    public function getDeclaredFeatures($searchEngine);

    /**
     * Checks if a particular search feature is supported
     *
     * @param string $featureName
     * @param string $searchEngine
     * @return bool
     */
    public function isFeatureSupported($featureName, $searchEngine);
}

So this configuration is obviously meant to declare supported features for different search engines (MySQL, ElasticSearch, ...), currently only "synonyms".

As of Magento CE 2.1 this is used in

  • Magento\Search\Model\SearchEngine\MenuBuilder - a plugin that removes the "Search Terms" entry in the backend if the current search engine does not support synonyms
  • Magento\Search\Controller\Adminhtml\Synonyms\ResultPageBuilder - if you go to the search terms page anyways, you will see a notice

Can one declare a different search engine by creating a search_engine.xml file? If so, is there anything else to declare a new search engine?

No, you only define the supported features here. The engine is defined via di.xml. This is how the Search module adds the "mysql" engine to the selectable engines in the configuration:

<type name="Magento\Search\Model\Adminhtml\System\Config\Source\Engine">
    <arguments>
        <argument name="engines" xsi:type="array">
            <item name="mysql" xsi:type="string">MySQL</item>
        </argument>
    </arguments>
</type>

Here it adds the MySQL adapter for searching:

<type name="Magento\Search\Model\AdapterFactory">
    <arguments>
        <argument name="adapters" xsi:type="array">
            <item name="mysql" xsi:type="string">Magento\Framework\Search\Adapter\Mysql\Adapter</item>
        </argument>
    </arguments>
</type>

And this how the CatalogSearch module defines the engine implementation for indexing:

<type name="Magento\CatalogSearch\Model\ResourceModel\EngineProvider">
    <arguments>
        <argument name="engines" xsi:type="array">
            <item name="mysql" xsi:type="string">Magento\CatalogSearch\Model\ResourceModel\Engine</item>
        </argument>
    </arguments>
</type>

There are a few more classes of the CatalogSearchModule that are different based on the selected engine:

<type name="Magento\CatalogSearch\Model\Indexer\IndexerHandlerFactory">
    <arguments>
        <argument name="configPath" xsi:type="const">Magento\CatalogSearch\Model\ResourceModel\EngineInterface::CONFIG_ENGINE_PATH</argument>
        <argument name="handlers" xsi:type="array">
            <item name="mysql" xsi:type="string">Magento\CatalogSearch\Model\Indexer\IndexerHandler</item>
        </argument>
    </arguments>
</type>

...

<type name="Magento\CatalogSearch\Model\Indexer\IndexStructureFactory">
    <arguments>
        <argument name="configPath" xsi:type="const">Magento\CatalogSearch\Model\ResourceModel\EngineInterface::CONFIG_ENGINE_PATH</argument>
        <argument name="structures" xsi:type="array">
            <item name="mysql" xsi:type="string">Magento\CatalogSearch\Model\Indexer\IndexStructure</item>
        </argument>
    </arguments>
</type>

...

<type name="Magento\Framework\Search\Dynamic\IntervalFactory">
    <arguments>
        <argument name="configPath" xsi:type="const">Magento\CatalogSearch\Model\ResourceModel\EngineInterface::CONFIG_ENGINE_PATH</argument>
        <argument name="intervals" xsi:type="array">
            <item name="mysql" xsi:type="string">Magento\Framework\Search\Adapter\Mysql\Aggregation\Interval</item>
        </argument>
        <argument name="scope" xsi:type="const">Magento\Store\Model\ScopeInterface::SCOPE_STORE</argument>
    </arguments>
</type>

...

<type name="Magento\Framework\Search\Dynamic\DataProviderFactory">
    <arguments>
        <argument name="configPath" xsi:type="const">Magento\CatalogSearch\Model\ResourceModel\EngineInterface::CONFIG_ENGINE_PATH</argument>
        <argument name="dataProviders" xsi:type="array">
            <item name="mysql" xsi:type="string">Magento\CatalogSearch\Model\Adapter\Mysql\Dynamic\DataProvider</item>
        </argument>
        <argument name="scope" xsi:type="const">Magento\Store\Model\ScopeInterface::SCOPE_STORE</argument>
    </arguments>
</type>

You will notice that in di.xml, factories are configured and the "engine" configuration is passed indirectly as $configPath argument. If you adhere to the standard fulltext search indexer which uses these factories, you will need to add implementations of all these interfaces for your engine.


Is it somehow related to the search_request.xml file?

It's both related to the search, so "somehow", yes. But search_request.xml is independent of the engine if I understand it right.