Instantsearch.js: Ability to target multiple indices using a single searchbar

Created on 30 Nov 2015  路  19Comments  路  Source: algolia/instantsearch.js

Let take the example of our Homepage demo, if we want do do something similar :
image

So search 1 movies index and 1 actors index. To be able to do it right now we have to do a custom widget to handle it.

Some ideas to handle it more easily:

  • we could have a option in the hit widget
  • we could have a widget to handle that

I also think about some other use-cases like for searching for authors in wordpress

What do you think ?

Needs Investigation

Most helpful comment

Given all the comments I will try to summarize what we should do.

Most of the issues here are about "I want to be able to use a single searchBox to search into different indices" so let's solve this issue on an API side.

Possible solutions:

  • provide a way to target multiple indices in instantsearch

I cannot think of any good API to do so. Because a refinement widget always belong to a particular indice. So we would also have to provide an API way to say "this refinement widget is targeting this particular index".

If we implement multi index at this level then it will cripple the whole API.

  • provide a way to target different indices in the hits() widget

Again this is tricky because facets/searchParameters will need to then be specified for multiple indices.

  • provide a way to link different instantsearch.js instances/searchBoxes

This is our best option I think. It all boils down to making this:

var searchMovies = instantsearch();
var searchActors = instantsearch();

var searchBox = instantsearch.widgets.searchBox({...});
searchMovies.addWidget(searchBox);
searchActors.addWidget(searchBox);

Works.

So this is more of an implementation issue. Please instantsearch.js users/devs let me know if this last API proposal would work for you and then we can move on to actual implementation issue.

All 19 comments

(for the record, the home page of algolia.com is doing a single search in movies, the actors are facets :p)

Yes I knew :smile:, the idea was more to be able to do it with two queries

Yes, we'll need that for sure.

At the end, it's kind of second instantsearch instance that uses an existing searchbar and that will probably deal with totally different query parameters. That being said, in some cases you'll need to use the same filters on both instances.

I'm thinking about something like:

var searchMovies = instantsearch({ application_id: ...., api_key: ....., index: 'movies' });
searchMovies.addWidget(instantsearch.widgets.searchBox({...}));

var searchActors = instantsearch({ application_id: ...., api_key: ....., index: 'actors' });
searchMovies.bindInstantSearch(searchActors); // FIXME: naming :)

// movies-specific widget
var widget1 = .....;
searchMovies.addWidget(widget1);

// actors-specific widget
var widget2 = .....;
searchActors.addWidget(widget2);

// shared widgets: the underlying filtering need to be applied on both movies & actors index
var widget3 = .....;
searchMovies.addWidget(widget3);
searchActors.addWidget(widget3); // FIXME: ensure the init/rendering is not done twice. :/

searchMovies.start();
searchActors.start(); // maybe not needed?

:+1: That would be super nice

Why not just:

var searchMovies = instantsearch();
var searchActors = instantsearch();

var searchBox = instantsearch.widgets.searchBox({...});
searchMovies.addWidget(searchBox);
searchActors.addWidget(searchBox);

This should already be feasible I think.

I'll test that

I think it will fail implementation wise because too much listeners etc..

But we should just make it work because sharing a searchbox should not require any other API point I think.

@vvo It won't work, each instantsearch will render the searchbox with its own helper.

This issue should probably be solved on the helper side, don't you think? Not sure...

But we should just make it work because sharing a searchbox should not require any other API point I think.

Yes correct, would be better than my binding. So if I update my proposal:

var searchMovies = instantsearch({ application_id: ...., api_key: ....., index: 'movies' });
var searchActors = instantsearch({ application_id: ...., api_key: ....., index: 'actors' });

// shared search box
var searchBox = instantsearch.widgets.searchBox({...});
searchMovies.addWidget(searchBox);
searchActors.addWidget(searchBox);

// movies-specific widget
var widget1 = .....;
searchMovies.addWidget(widget1);

// actors-specific widget
var widget2 = .....;
searchActors.addWidget(widget2);

// shared widgets: the underlying filtering need to be applied on both movies & actors index
var widget3 = .....;
searchMovies.addWidget(widget3);
searchActors.addWidget(widget3); // FIXME: ensure the init/rendering is not done twice. :/

searchMovies.start();
searchActors.start();

@vvo It won't work, each instantsearch will render the searchbox with its own helper.

Yeah we need to find a way to add the same widget multiple times but:

  • render it once only (totally fine to say that it's the 1st instantsearch instance that renders it)
  • probably tricky to share the state modifications to the underlying helpers but we'll need to

@redox @vvo My bad it should work with the searchbox because it is only rendered once on init

Yeah no it doesn't work, different helpers.

Maybe only the searchbox may support this for now?

Implementation idea : if the init is called multiple times, store the helper each time, then when onKeyPress is called helper.setQuery(myQuery).search() for each helper registered?

Hi, I am trying to do the same with my two separate searches. I would like to combine these two separate searches/indices (bikes, parts) into one:

The flow is that bike mechanics will search for both bikes and, at some point, the parts needed to service those bikes. Right now, they might find their bike in the Product Finder search, see the list of available parts, then go look for it in the Service Parts Finder. There is a way to drilldown to the service parts for the bike, but sometimes users are simply searching for a part without the need to drill into a bike (they might not be servicing a specific bike, but might just be in need of a derailleur hanger, for example).

It'd be nice if they were in the same results page, then just facet-filter to get what they need. I would like to make Service Parts a facet filter on the Bikes search (under Bikes, Shoes, Wheels, and Command Post).

Anyway, any ideas/solutions would be nice. I had originally started writing this using the algoliasearch library. I switched over to instantsearch due to the URL sync feature, which was easy to implement. But now, after this feature request, I've learned that multiple index search with one searchbar is not (currently) supported with instantsearch.js.

Given all the comments I will try to summarize what we should do.

Most of the issues here are about "I want to be able to use a single searchBox to search into different indices" so let's solve this issue on an API side.

Possible solutions:

  • provide a way to target multiple indices in instantsearch

I cannot think of any good API to do so. Because a refinement widget always belong to a particular indice. So we would also have to provide an API way to say "this refinement widget is targeting this particular index".

If we implement multi index at this level then it will cripple the whole API.

  • provide a way to target different indices in the hits() widget

Again this is tricky because facets/searchParameters will need to then be specified for multiple indices.

  • provide a way to link different instantsearch.js instances/searchBoxes

This is our best option I think. It all boils down to making this:

var searchMovies = instantsearch();
var searchActors = instantsearch();

var searchBox = instantsearch.widgets.searchBox({...});
searchMovies.addWidget(searchBox);
searchActors.addWidget(searchBox);

Works.

So this is more of an implementation issue. Please instantsearch.js users/devs let me know if this last API proposal would work for you and then we can move on to actual implementation issue.

We've been looking at implementing a full site search using multiple indexes and this feature would make doing so much nicer. We're currently having to place all the entities in one index which doesn't seem to the best approach.

@davidpike7 Just to be sure, can you walk us through your usecase if it is different as the one from this issue: "Allow searchbox to target multiple indices" which only does what it says, it does not for example take into account having a hits widget mixing multiple indices results if that's what you are looking for.

Explain us your usecase if different so that we better understand if the current proposal could fit.

@vvo As it stands we would like to a hits widget for each index but then use one searchbox and show/hide each index using tabs. Sort of like the product hunt implementation.

@davidpike7 The best way to do so currently would be to create one instance of instantsearch.js per tab and then hide/show the whole interface given the selected tab.

Was this page helpful?
0 / 5 - 0 ratings