Multi Index Search
On this page
Overview
It might happen that you want to search across multiple indices at the same time. React InstantSearch has a built-in solution for this use case, the Index
component. The widgets scoped under this Index
component will target the provided index. The widgets that are not scoped under an Index
are “shared” across all the indices. This widget is really useful whenever you want to:
- display hits from different indices
- share a single
SearchBox
- build an autocomplete menu targeting different indices
In this guide we will learn how to share a single SearchBox
to display multiple hits from different indices. We will also take a look at how to create an autocomplete that targets multiple indices. The source code of both examples can be found on GitHub.
Search in multiple indices
For this first use case we share a single SearchBox
to search into multiple indices. Both Hits
widgets are scoped under an Index
component. It means that they are restricted to display results from this particular index. In the first case the instant_search
and in the second case instant_search_price_desc
.
If you want to perform a multi index search on the same index (for example, to trigger several searches on the same index with different parameters), make sure to define the indexId
property on your Index
widgets.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import algoliasearch from 'algoliasearch/lite';
import {
InstantSearch,
Index,
SearchBox,
Hits
} from 'react-instantsearch-dom';
const searchClient = algoliasearch(
'latency',
'6be0576ff61c053d5f9a3225e2a90f76'
);
const App = () => (
<InstantSearch indexName="instant_search" searchClient={searchClient}>
<SearchBox />
<Index indexName="instant_search">
<h2>index: instant_search</h2>
<Hits />
</Index>
<Index indexName="instant_search_price_desc">
<h2>index: instant_search_price_desc</h2>
<Hits />
</Index>
</InstantSearch>
);
Not only the Hits
widget can be scoped under an Index
component, but every widget can be used. In the following example we want to display a different number of results in our two sets of results. instant_search
index will display 8 results and instant_search_price_desc
16 results. To restrict the number of results per page we use the Configure
widget. Each widget will be scoped under the index that we want to target.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import algoliasearch from 'algoliasearch/lite';
import {
InstantSearch,
Index,
Configure,
SearchBox,
Hits
} from 'react-instantsearch-dom';
const searchClient = algoliasearch(
'latency',
'6be0576ff61c053d5f9a3225e2a90f76'
);
const App = () => (
<InstantSearch indexName="instant_search" searchClient={searchClient}>
<SearchBox />
<Index indexName="instant_search">
<h2>index: instant_search</h2>
<Configure hitsPerPage={8} />
<Hits />
</Index>
<Index indexName="instant_search_price_desc">
<h2>index: instant_search_price_desc</h2>
<Configure hitsPerPage={16} />
<Hits />
</Index>
</InstantSearch>
);
You can find the complete example on GitHub.
Autocomplete
For this second use case, we are building an autocomplete that searches into multiple indices. The focus of this guide is on search into multiple indices. We do not cover the autocomplete implementation in depth because it has its own guide. The autocomplete is built with React Autosuggest and the Autocomplete
connector. Note that the shape of the hits
argument changes depending on whether it’s used in a single- or multi-index context. In a single index context the value is an array of hits. But in a multi-index context the value is an array of objects that contain two properties index
and hits
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import { Highlight, connectAutoComplete } from 'react-instantsearch-dom';
import AutoSuggest from 'react-autosuggest';
class AutoComplete extends Component {
state = {
value: this.props.currentRefinement,
};
onChange = (event, { newValue }) => {
this.setState({
value: newValue,
});
};
onSuggestionsFetchRequested = ({ value }) => {
this.props.refine(value);
};
onSuggestionsClearRequested = () => {
this.props.refine();
};
getSuggestionValue(hit) {
return hit.name;
}
renderSuggestion(hit) {
return <Highlight attribute="name" hit={hit} tagName="mark" />;
}
renderSectionTitle(section) {
return section.index;
}
getSectionSuggestions(section) {
return section.hits;
}
render() {
const { hits, onSuggestionSelected } = this.props;
const { value } = this.state;
const inputProps = {
placeholder: 'Search for a product...',
onChange: this.onChange,
value,
};
return (
<AutoSuggest
suggestions={hits}
multiSection={true}
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
onSuggestionSelected={onSuggestionSelected}
getSuggestionValue={this.getSuggestionValue}
renderSuggestion={this.renderSuggestion}
inputProps={inputProps}
renderSectionTitle={this.renderSectionTitle}
getSectionSuggestions={this.getSectionSuggestions}
/>
);
}
}
export default connectAutoComplete(AutoComplete);
Once we have our autocomplete component we can use with it in our multi-index application. The component will have access to both indices. It will also leverage the Configure
to reduce the number of hits.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import algoliasearch from 'algoliasearch/lite';
import { InstantSearch, Index, Configure } from "react-instantsearch-dom";
import AutoComplete from "./AutoComplete";
const searchClient = algoliasearch(
'latency',
'6be0576ff61c053d5f9a3225e2a90f76'
);
const App = () => (
<InstantSearch indexName="instant_search" searchClient={searchClient}>
<Configure hitsPerPage={3} />
<AutoComplete />
<Index indexName="instant_search" />
<Index indexName="instant_search_price_desc" />
</InstantSearch>
);
You can find the complete example on GitHub.