Sum up all hits in a multi index search

We make PDF catalogues searchable. Each catalog has its own index in algolia. So I am doing a multi index search in the frontend. Is there any way to sum up the total hits from each index?

  • catalog_1: nbHits: 15
  • catalog_2: nbHits: 20

Result should be: Total Hits: 35

Firstly to show the user how many results there are in total with his query and then to show a message if there is in total no result.

Here is the code to my component:

<template>
    <div v-if="query.length > 0 && catalogs.length > 0">
        <ais-instant-search
                v-for="(catalog, key) in catalogs"
                :key="key"
                :search-client="searchClient"
                :index-name="catalog.indexName"
        >
            <ais-configure
                    :query="query"
                    :attributesToSnippet="['bodytext']"
            />

            <ais-stats>
                <template slot-scope="{ nbHits }">
                    {{ nbHits }}
                </template>
            </ais-stats>
        </ais-instant-search>
    </div>
</template>

<script>
    export default {
        props: ['searchClient', 'query', 'facets'],
        computed: {
            catalogs() {
                return this.$root.$data.state.config.catalogs;
            }
        },
    }
</script>

Thanks for your help in advance!

I have found a solution, but I doubt whether this is the best solution.

I store in an array counts[] an object with the index and the respective hits. To store the data I have a countHit(indexName, hits) method which I call in the template and pass the nbHits there.

Then I have a method totalHits() which counts the hits.

<template>
    <div v-if="query.length > 0 && catalogs.length > 0">
        <h1>{{ totalHits() }}</h1>

        <ais-instant-search
                v-for="(catalog, key) in catalogs"
                :key="key"
                :search-client="searchClient"
                :index-name="catalog.indexName"
        >
            <ais-configure
                    :query="query"
                    :attributesToSnippet="['bodytext']"
            />

            <ais-stats>
                <template slot-scope="{ nbHits }">
                    {{ countHit(catalog.indexName, nbHits) }}

                    {{ nbHits }}
                </template>
            </ais-stats>
        </ais-instant-search>
    </div>
</template>

<script>
    export default {
        props: ['searchClient', 'query', 'facets'],
        data() {
            return {
                counts: [],
            }
        },
        computed: {
            catalogs() {
                return this.$root.$data.state.config.catalogs;
            }
        },
        methods: {
            countHit(indexName, hits) {
                const item = this.counts.find(item => item.indexName === indexName);

                if (item === undefined) {
                    this.counts.push({indexName, hits});
                } else {
                    item.hits = hits;
                }
            },
            totalHits() {
                let count = 0;

                this.counts.forEach(item => count += item.hits);

                return count;
            }
        }
    }
</script>

I am still happy about feedback.

Hi there,
Thanks for reaching out to us.

While your solution might work, I’ve made another example for you.

I created a new component which uses connectStats connector.

<template>
  <div></div>
</template>	

<script>
import { createWidgetMixin } from 'vue-instantsearch';
import { connectStats } from 'instantsearch.js/es/connectors';

export default {
  mixins: [
    createWidgetMixin({ connector: connectStats })
  ],
  computed: {
    nbHits() {
      return this.state && this.state.nbHits;
    }
  },
  watch: {
    nbHits() {
      this.$emit("nbHitsChange", this.nbHits);
    }
  }
};
</script>

It sends the changed nbHits to its parent. And you can receive it at the parent like the following:

<stat @nbHitsChange="nbHitsChange" />

Then you can do whatever you want to do with the number.

If you want to learn more about creating your own components, this should be helpful.

And let me know if you have any other question :slight_smile:

This looks like a much better solution. Thanks!

Glad to hear that!
Don’t hesitate to reach out to us if you have any other question.

Have a nice day :slight_smile: