Multi-index search with Angular InstantSearch
Angular InstantSearch isn’t compatible with Angular’s Ivy view engine. We’re investigating how best to support this. For more information and to vote for Algolia’s support of Angular 16 and beyond, see the GitHub issue Algolia Support for Angular InstantSearch
On this page
Multi-index search (federated search) is a method for searching multiple data sources simultaneously. This means that when users enter a search term, Algolia will look for and display results from all these data sources.
This doesn’t necessarily mean that the results from Algolia indices are combined since their contents could be quite different. Your approach may be to display the results from each index separately. You could display the top-rated items from a movie index alongside the list of results from a book index. Or you could display category matches alongside the list of results from a product index
Search multiple indices with InstantSearch
This example uses a single input to search multiple indices. It uses the ais-index
to query two indices at the same time: players
and actors
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// app.component.ts
import { Component } from '@angular/core';
import algoliasearch from 'algoliasearch/lite';
const searchClient = algoliasearch(
'latency',
'6be0576ff61c053d5f9a3225e2a90f76'
);
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
config = {
indexName: 'instant_search',
searchClient,
};
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- app.component.html -->
<ais-instantsearch [config]="config">
<ais-search-box placeholder=""></ais-search-box>
<ais-index indexName="actors">
<h2>Actors</h2>
<ais-hits></ais-hits>
</ais-index>
<ais-index indexName="players">
<h2>Players</h2>
<ais-hits></ais-hits>
</ais-index>
</ais-instantsearch>
The example uses a custom search box and injects the query into two InstantSearch instances with the ais-configure
component.
Search multiple indices with Autocomplete
This example builds an Autocomplete to search multiple indices. It’s built with Angular Material’s Autocomplete and the connectAutocomplete
component. The only difference to the previous guide is how hits are appended to Autocomplete.
The ais-autocomplete
component takes indices
as a prop. This is an array of additional indices to search, in this case, the actors
index.
First, ensure you have the correct setup to use Angular Material UI components, then import MatInputModule and MatAutocompleteModule inside your project.
$
ng add @angular/material
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
import { NgAisModule } from 'angular-instantsearch';
import { MatInputModule, MatAutocompleteModule } from '@angular/material';
@NgModule({
declarations: [
AppComponent
],
imports: [
NgAisModule.forRoot(),
BrowserModule,
BrowserAnimationsModule,
MatInputModule,
MatAutocompleteModule,
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Now create a new component autocomplete.component.ts
inheriting from BaseWidget
and connect it to your instant-search instance to connectAutocomplete
.
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
// autocomplete.component.ts
import {
Component,
Inject,
forwardRef,
Output,
EventEmitter, Optional
} from "@angular/core";
import {NgAisIndex, NgAisInstantSearch, TypedBaseWidget} from "angular-instantsearch";
import {connectAutocomplete} from "instantsearch.js/es/connectors";
import {
AutocompleteWidgetDescription,
AutocompleteConnectorParams
} from "instantsearch.js/es/connectors/autocomplete/connectAutocomplete";
@Component({
selector: 'app-autocomplete',
template: ` ... `,
})
export class AutocompleteComponent extends TypedBaseWidget<
AutocompleteWidgetDescription,
AutocompleteConnectorParams
> {
state: AutocompleteWidgetDescription['renderState'] = {
currentRefinement: '',
refine: () => null,
indices: [],
};
@Output() onQuerySuggestionClick = new EventEmitter<{ query: string }>();
constructor(
@Inject(forwardRef(() => NgAisIndex))
@Optional()
public parentIndex: NgAisIndex,
@Inject(forwardRef(() => NgAisInstantSearch))
public instantSearchInstance: NgAisInstantSearch
) {
super('Autocomplete');
this!.createWidget(connectAutocomplete, {});
}
public handleChange($event: KeyboardEvent) {
this.state.refine(($event.target as HTMLInputElement).value);
}
public ngOnInit() {
super.ngOnInit();
}
}
Now you just need to use the Angular Material Autocomplete component and feed it with the data from the indices.
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
// autocomplete.component.ts
@Component({
selector: 'app-autocomplete',
template: `
<div>
<input
matInput
[matAutocomplete]="auto"
(keyup)="handleChange($event)"
style="width: 100%; padding: 10px"
/>
<mat-autocomplete #auto="matAutocomplete" style="height: 800px">
<div *ngFor="let index of state.indices.slice(1) || []">
<mat-optgroup>{{ index.indexName }}</mat-optgroup>
<mat-option
*ngFor="let option of index.hits"
[value]="option.name"
(click)="onQuerySuggestionClick.emit({ query: option.name })"
>
<ais-highlight [hit]="option" attribute="name"></ais-highlight>
</mat-option>
</div>
</mat-autocomplete>
</div>
`
})
export class Autocomplete extends TypedBaseWidget<...> { /* ... */ }
Now use the newly created Autocomplete component in your code.
1
2
3
4
5
6
<ais-instantsearch [config]="config">
<ais-configure [searchParameters]="{ hitsPerPage: 3 }"></ais-configure>
<ais-index indexName="players"></ais-index>
<ais-index indexName="actors"></ais-index>
<app-autocomplete></app-autocomplete>
</ais-instantsearch>
The Autocomplete component is now searching in two indices: players
and actors
.
The focus of this guide is on searching multiple indices. The Autocomplete implementation isn’t covered in depth because it has a dedicated guide.
Category display
Algolia can help you display both category matches and results if you:
- Add categories to your Query Suggestions either inline or listed below a result. For example, you might see the following in your Query Suggestions list “game of thrones in Books”
- Use multi-index search to display categories from a separate category index. This is useful if you want to display categories and Query Suggestions at the same time. Clicking such a result typically redirects to a category page. The following is a sample dataset for a product index and a category index.
Example product index
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[
{
"name": "Fashion Krisp",
"description": "A pair of red shoes with a comfortable fit.",
"image": "/fashion-krisp.jpg",
"price": 18.98,
"likes": 284,
"category": "Fashion > Women > Shoes > Court shoes"
},
{
"name": "Jiver",
"description": "A blue shirt made of cotton.",
"image": "/jiver.jpg",
"price": 17.70,
"likes": 338,
"category": "Fashion > Men > Shirts > Dress shirt"
}
]
Example category index
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
{
"name": "Court shoes",
"category": "Fashion > Women > Shoes > Court shoes",
"description": "A dress shoe with a low-cut front and a closed heel.",
"url": "/women/shoes/court/"
},
{
"name": "Dress shirt",
"category": "Fashion > Men > Shirts > Dress shirt",
"description": "A long-sleeved, button-up formal shirt that is typically worn with a suit or tie.",
"url": "/men/shirts/dress/"
}
]