Remove parameters of additional queries in multiple indexes search

I’m following this rule to retrieve results from multiple queries. If I add a menu widget to the first index, it will add the menu’s attribute to query parameter. For example If I add brand menu, facets=%5B%22brand%22%5D or facets=[\"brand\"] will be added to the query. If I also add a new query to another index:

instantsearch.widgets
    .index({ indexName: 'instant_search_price_desc' })
    .addWidgets([
      instantsearch.widgets.configure({
        hitsPerPage: 4,
      }),

      instantsearch.widgets.hits({
        container: '#hits-instant-search-2',
        templates: {
          item:
            '{{#helpers.highlight}}{ "attribute": "name" }{{/helpers.highlight}}',
        },
      }),
    ])

the params from first index’s query will be in the second query as well.

However, I don’t want the params to carry over from first query to other additional queries unless it is currently active, so the results of the second query won’t have the facet data of brand in my example. How can I do that?

What I’ve tried so far without any luck (codesandbox link):

  • Use custom widget and helper to remove facets:
instantsearch.widgets
    .index({ indexName: 'instant_search_price_desc' })
    .addWidgets([
    ...
    {
      init(data) {
        data.helper.setQueryParameter('facets', []);
      }
    }
    ])
  • Use removeWidgets function on search object:
instantsearch.widgets
    .index({ indexName: 'instant_search_price_desc' })
    .addWidgets([
    ...
    ]).removeWidgets([brandWidget])

Hi,

You where not far from the solution.

What you can do is:

  • first, add widgets for all indices like so:
search.addWidgets([
  instantsearch.widgets.configure({
    hitsPerPage: 4,
  }),
  instantsearch.widgets.searchBox({
    container: '#searchbox',
  }),
]);
  • then, you can add widgets that will act on your first index only:
search.addWidgets([
  instantsearch.widgets
    .index({ indexName: 'first_index_name' })
    .addWidgets([
      instantsearch.widgets.menu({
        container: '#brand',
        attribute: 'brand'
      }),
      instantsearch.widgets.hits({
        container: '#hits-instant-search',
        templates: ...,
      }),
    ])
]);
  • and do the same for your other index:

search.addWidgets([
  instantsearch.widgets
    .index({ indexName: 'second_index_name' })
    .addWidgets([
      instantsearch.widgets.menu({
        container: '#categories',
        attribute: 'categories'
      }),
      instantsearch.widgets.hits({
        container: '#hits-instant-search-2',
        templates: ...,
      }),
    ])
]);

Let us know how it goes,

1 Like

Hi @emmanuel.krebs,

Thank you for your response. It is working, but each menu is refining only its own hits. What I want is each menu will refine all indexes. So in the codesandbox example, if I choose a brand, it not only refines the instant_search hits but also refines the instant_search_2 hits. I tried using custom menu but it is not working:

const {
    ...
    instantSearchInstance
  } = renderOptions;

instantSearchInstance.helper.toggleFacetRefinement('brand', 'Apple');

This exception occurred:

Uncaught Error: Cannot refine the undeclared facet brand; it should be added to the helper options facets, disjunctiveFacets or hierarchicalFacets

Is that possible?

If I understand well, you would like to refine the two indices whenever you interact with one of the menu.

To do so, you need to move the two menu widgets to the root of the widgets’ tree. I updated your example: see sandbox.

Hi @francoischalifour,

Thank you for your answer but that is not what I want. I need to implement multi-indexes search with these requirements:

  • The base index in instant_search index with brand as menu
  • The second index also in instant_search index with categories as facet, this index need to be refined by brand menu in the base index, but its response should not contains brand facets, only categories facets to build its own menu. (This is partially resolved with @emmanuel.krebs’ answer, each index has its own facets response now but their menus does not affect others results)
  • On the contrary, if you select a category in categories menu of the second index, it should refine both indexes and the base index response should only contain brand facets.

Hope you can understand what I mean. Please tell me if the above conditions is possible to implement.

Could you show what you have or want as an UI in a sandbox, with still the wrong synchronisation behaviour? I’m having a hard time wrapping my head around what you expect as an outcome. Thanks!

Hi @haroen,

Here is the sandbox. Each refinement menu is defined in a separated index call. If you use your browser console to check the response, you can see it returns 3 results, the first one of main index and the last two are the results for each menu I defined. Each result has its own facets and partially used to build the UI. If you try to select something in the menu, it will not change the hits displayed. I want to make multiple indexes search like that and the menus can still refine the hits.

I know I can just include all of the facets in a single index call. But I’m working with a site, in which the engine will cut off the facets if I include them all in one call.

Thank you

Hello @thungthudh

This example is not exactly same with what you say, but in the sandbox, you’ll see how onStateChange can be used to control the state.

So basically, in the example, whatever happens to search, before the http request, onStateChange will be called. There you can create a new uiState to apply some facets, queries, or whatever to any index. And you can set the new uiState, then the search api will be called with the new uiState.

You can read more here: instantsearch | InstantSearch.js | API parameters | API Reference | Algolia Documentation

Let me know if this solves your issue.