Building a custom module where I need to search on the third-party table for data.

I have executed and filtered data from the third-party table and retrieve the entity_id from it and added the entity_id the below query.

$this->queryResponse = $this->searchEngine->search($queryRequest);
    $ids = [0];

    $productIds = $this->crossReferenceFactory->getProductIdsBySearch($this->queryText);

        foreach($productIds as $id) 
            $ids[] = $id;   

    /** @var \Magento\Framework\Search\Document $document */
    foreach ($this->queryResponse as $document) {
        $ids[] = $document->getId();
    parent::addFieldToFilter('entity_id', ['in' => $ids]);

When I do such filter it lists the products perfectly fine, But when I query for words which exist only in the third-party table it doesn't build the layered navigation.

After debugging I come to know that layered navigation uses below method.

public function getFacetedData($field)
    $aggregations = $this->queryResponse->getAggregations();
    $bucket = $aggregations->getBucket($field . '_bucket');
    if (!$bucket) {
        throw new StateException(new Phrase('Bucket does not exist'));
    $result = [];
    foreach ($bucket->getValues() as $value) {

        $metrics = $value->getMetrics();
        $result[$metrics['value']] = $metrics;

    return $result;

So, When I search for any particular word it builds the layered navigation using queryResponse data.

My concern is how can I add my table to $queryRequest so that I can have a consistent result. Any help would highly appreciate.

  • Hi, Did you find solution for this? I am facing same issue. Please answer if you found please share here. Oct 4 '16 at 12:30
  • i am also facing same issue can any one share the answer? Sep 11 '17 at 9:17

if you want to remove the dependency on Magento Fulltext catalog search then rewrite Magento/CatalogSearch/Model/Search/IndexBuilder.php file in your custom module and change SQL query(which will get data from your custom table) in function public function build (RequestInterface $request) then layer navigation filters also work properly.


The sample code for overriding Magento\CatalogSearch\Model\Search\IndexBuilder is as follows:


<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\CatalogSearch\Model\Search\IndexBuilder">
        <plugin name="Namespace_Modulename::custom_collection" type="Namespace\Modulename\Plugin\CatalogSearch\Model\Search\IndexBuilder" />


namespace Namespace\Modulename\Plugin\CatalogSearch\Model\Search;

use Magento\Framework\Search\RequestInterface;

class IndexBuilder {    
    protected $_request;
    protected $_categoryHelper;

    public function __construct(
        \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
        \Magento\Catalog\Helper\Category $categoryHelper,
        \Magento\Framework\App\Request\Http $request
    ) {
        $this->_productCollectionFactory    = $productCollectionFactory;
        $this->_categoryHelper              = $categoryHelper;
        $this->_request                     = $request;

    public function aroundBuild($subject, callable $proceed, RequestInterface $request) {
        $select = $proceed($request);

        $collection = $this->_productCollectionFactory->create();
        $collection->addAttributeToFilter('necessary_attribute', ['necessary_attribute' => 'attr_value']);
        $getProductAllIds = $collection->getAllIds();
        $productUniqueIds = array_unique($getProductAllIds);
        $select->where("search_index.entity_id IN ('" . join("','", $productUniqueIds) . "')");     
        return $select;

Hope this may help you guys!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.