Overview

There are times when your content is spread across multiple search indexes, e.g. if you're serving users in different geographies and have search data in multiple languages, it makes sense to have data for each language as its own index. Or when you have data coming from different sources and each source is represented as its own index.

In this guide, we are going to see how to search across multiple indexes using the ReactiveSearch library.

Use Cases

Combine results from multiple indices

In this example, we are going to create an app which retrieves results from two indices good-books-ds and good-books. Both the indices are similar and contain information about books. We would fetch results from both indices and tag them by index.

When we want to use multiple indices then we need to specify it using app property on ReactiveBase. We need to separate the indices by comma. You can also use the index property on UI components from reactivesearch to have the same effect. index overrides the app property of ReactiveBase.

Copy
<ReactiveBase
    app="good-books,good-books-ds"
    //...more props
/>

We also need to make sure that the API credentials we use have been allowed access to both the search indices.

In order to search, we would require a searchbar. We can make a searchbar by using SearchBox from reactivesearch. We give it a defaultValue of Harry Potter. We search on the original_title field. You can also specify index property which is optional.

Copy
<SearchBox
    title="SearchBox"
    defaultValue="Harry Potter"
    dataField="original_title"
    componentId="BookSensor"
    size={10}
    index="good-books,good-books-ds"
/>

When a user would search, the results (aka hits) will be fetched from both the indices. We can use the _index property of reh results to annotate them on the basis of which index they're coming from. We show it as different colored badges in the UI. For rendering the results we use ReactiveList.

You can see a live example below:

Using different index for facet/filter

Sometimes we have separate indexes to store relational or related information. e.g. authors and books. But we might want to filter books by selecting from a list of authors. In this example we are exactly going to do that.

We would be using two indexes good-books-ds and good-books-authors. Inside of good-books-authors in dashboard we need to add author_name as aggregation.

Author aggregations setting

To choose from different authors, we will set a facet filter. We can use the MultiList component for this. Notice the index here is good-books-authors and the dataField is author_name.keyword.

Copy
<MultiList
    componentId="BookSensor"
    dataField="author_name.keyword"
    index="good-books-authors"
    aggregationSize={100}
/>

We will use a ReactiveList component to display results. This component would be connected to good-books-ds.

Copy
<ReactiveList
    componentId="SearchResult"
    dataField="original_title"
    className="result-list-container"
    index="good-books-ds"
    from={0}
    size={5}
    renderItem={this.booksReactiveList}
    react={{
        and: ['BookSensor'],
    }}
/>

In this scenario, we will also need to configure the search query coming from the author selection so while the index queried for facet aggregations is good-books-authors, the index queried for the search results is good-books-ds. We do this by setting a customQuery which fetches data from the good-books-ds index.

Copy
<MultiList
    componentId="BookSensor"
    dataField="author_name.keyword"
    index="good-books-authors"
    // customQuery: If none is selected then match all documents else match selected
    customQuery={value => (value.length ? ({
        query: {
            terms: {
                'authors.keyword': value,
            },
        },
    }) : ({
        query: {
            match_all: {},
        },
    }))}
    aggregationSize={100}
/>

You can see a live example below: