Multi Index Search
On this page
Overview
It might happen that you want to search across multiple indices at the same time. Vue InstantSearch has a built-in solution for searching into multiple indices with an autocomplete component. Another common use case is to display hits from multiple indices at the same time. We don’t have a proper API for this use case but we can synchronize two Vue InstantSearch instance to have the same behavior.
In this guide we will learn how to share a single ais-search-box
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.
Hits from multiple indices
For this first use case we share a single ais-search-box
to search into multiple indices. For this behavior we use two ais-instant-search
instances. Each of them target a specific index, the first one is instant_search
and the second is instant_search_price_desc
.
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
<template>
<div>
<ais-instant-search
:search-client="searchClient"
index-name="instant_search_price_desc"
>
<ais-search-box v-model="query" />
<ais-configure
:restrictSearchableAttributes="['name']"
:hitsPerPage="8"
/>
<ais-hits>
<template slot="item" slot-scope="{ item }">
<h3><ais-highlight :hit="item" attribute="name" /></h3>
<img :src="item.image" />
</template>
</ais-hits>
</ais-instant-search>
<hr />
<ais-instant-search
:search-client="searchClient"
index-name="instant_search"
>
<ais-configure
:query="query"
:restrictSearchableAttributes="['name']"
:hitsPerPage="8"
/>
<ais-hits>
<template slot="item" slot-scope="{ item }">
<h3><ais-highlight :hit="item" attribute="name" /></h3>
<img :src="item.image" />
</template>
</ais-hits>
</ais-instant-search>
</div>
</template>
<script>
import algoliasearch from 'algoliasearch/lite';
export default {
data() {
return {
searchClient: algoliasearch(
'latency',
'6be0576ff61c053d5f9a3225e2a90f76'
),
query: '',
};
},
};
</script>
What’s to note here is that we make the ais-search-box
“controlled”. We keep track of the query in the query
data variable. Every time something changes in the first index, we will be notified via its change handler. Subsequently we apply that query to the other index, by making use of the ais-configure
component.
Note that since this is two dedicated instances we can apply different parameters and widgets to the search. This can be done by passing different parameters to ais-configure
or mounting different widgets in each of the ais-instant-search
components.
You can find the complete example on GitHub.
autocomplete
For this second use case we are gonna build an autocomplete to search into multiple indices. We are not going to talk too much about the autocomplete part. You can find a complete guide on the subject in the documentation. The autocomplete is built with Vue Autosuggest and the ais-autocomplete
component. The only difference with the previous guide is how we append the hits to the autocomplete.
The ais-autocomplete
component takes indices
as a prop. This is an array of additional indices to search into, in this case the instant_search_price_desc
index. Just like in the other guide, we will need to transform the results from Algolia into what the Vue Autosuggest component expects, except this time we will also need to make sure the shape of either hit is the same, to avoid too much logic in the template itself.
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
67
68
69
70
71
72
73
<template>
<div class="container">
<ais-instant-search
:search-client="searchClient"
index-name="instant_search"
>
<ais-configure
:hitsPerPage="5"
:restrictSearchableAttributes="['name']"
/>
<ais-autocomplete
:indices="[
{
value: 'instant_search_price_desc',
label: 'Price (desc)',
},
]"
>
<template slot-scope="{ currentRefinement, indices, refine }">
<vue-autosuggest
:suggestions="indicesToSuggestions(indices)"
@selected="onSelect"
:input-props="{
style: 'width: 100%',
onInputChange: refine,
placeholder: 'Search here…',
}"
>
<template slot-scope="{ suggestion }">
<ais-highlight
:hit="suggestion.item"
attribute="name"
v-if="suggestion.item.name"
/>
<strong>$ {{ suggestion.item.price }}</strong>
<img :src="suggestion.item.image" />
</template>
</vue-autosuggest>
</template>
</ais-autocomplete>
</ais-instant-search>
</div>
</template>
<script>
import algoliasearch from 'algoliasearch/lite';
import { VueAutosuggest } from 'vue-autosuggest';
export default {
components: { VueAutosuggest },
data() {
return {
searchClient: algoliasearch(
'latency',
'6be0576ff61c053d5f9a3225e2a90f76'
),
query: '',
};
},
methods: {
onSelect(selected) {
if (selected) {
console.log(selected);
}
},
indicesToSuggestions(indices) {
return indices.map(({ hits }) => ({
data: hits,
}));
},
},
};
</script>
You can find the complete example on GitHub.