Search the same index, with 2 queries and different RetrievableAttributes

Hi There,

My site has a single search box and my goal is to search the same Algolia index with 2 different search queries (“QueryA” and “QueryB”) in one go.

Additionally QueryA should return all the values (columns) while QueryB should only return some values from the index.

Example:
Searching for ‘searchkeyword’ in the search bar should do:
QueryA: Search “indexFoo” for rows with type = 1, content = ‘searchkeyword’ and return all values:
QueryB: Search “indexFoo” for rows with type = 7, content = ‘searchkeyword’ and return only value x & value y

Now as I saw I can probably use "Multi-Index Search" for doing two search queries on the same index.

Main question: How can I return different search attributes (columns) for QueryB and QueryA. I saw that I can define the returned values globally with “attributesToRetrieve” but can I define this per query?

Thanks for any tips,
Regards, Dominic

attributesToRetrieve is for the getObjects method, which is used more for index maintenance than frontend interfaces.

Multi-index search is the way to go here. You’ll get the full record back in both cases, but you can control what the user sees by defining different hit templates for the two searches.

This seems like a great use case for an autocomplete experience with a federated results block:

1 Like

Thank you for your answer @chuck.meyer , I did some research on this and on stackoverflow I found your solution to a similar issue. There the user wanted to search two different indices with each their own filter. I adapted this like this (see below) to search the SAME index twice, with 2 seperate filters:

 <ais-instant-search
        :search-client="searchClient_1"  // using searchClient_1 with filter settings 1
        index-name="my_main_index"
      >
        <ais-search-box v-model="query" />

        <ais-hits>
          <template slot="item" slot-scope="{ item }">
            <h3><ais-highlight :hit="item" attribute="name" /></h3>
            <img :src="item.image" />
          </template>
        </ais-hits>

        <hr />

        <ais-index :search-client="searchClient_2" index-name="my_main_index">  // using searchClient_2 with filter settings 2
         <ais-hits>
            <template slot="item" slot-scope="{ item }">
                <h3><ais-highlight :hit="item" attribute="name" /></h3>
                <img :src="item.image" />
            </template>
         </ais-hits>

Unfortunately this doesn’t work and I get the same result twice now, both with “filter settings 1”. I believe the searchClients/searchKeys are created correctly, so the issue must be that I’m using the widgets wrong here (probably the wrong ‘slot’?). Do you have another hint for me?

Aha, I think I got it working with the following structure in the VueJS-template.
I additionally created a data entry ‘query:‘’,’ and made the second search field invisible to only have one global search field for both with the same v-model ‘query’.

<template>
  <div>
    <ais-instant-search
        :search-client="this.searchClient_1"  //first search settings (1)
        index-name="my_main_index"
      >
        <ais-search-box v-model="query" />

        <ais-hits>
          <template slot="item" slot-scope="{ item }">
            <h3><ais-highlight :hit="item" attribute="Typ" />{{ item.foo}}({{ item.bar}})</h3>
          </template>
        </ais-hits>

  </ais-instant-search>

  <ais-instant-search
        :search-client="this.searchClient_2" index-name="my_main_index" //second search settings (2)
      >
        <ais-search-box v-show="0" v-model="query" /> //this second search field is needed, but hidden since I only need one global search field.

        <ais-hits>
          <template slot="item" slot-scope="{ item }">
            <h3><ais-highlight :hit="item" attribute="foo" />{{ item.foo}}({{ item.bar}})</h3>
          </template>
        </ais-hits>

  </ais-instant-search>
  </div>
</template>

export default {
  name: "search-foo",
[..]
  data() {
    return {
      query:'',
[..]

And for the partial result (filter settings 2) I used attributesToRetrieve in the generateSecuredApiKey function:

$securedApiKey_store = \Algolia\AlgoliaSearch\SearchClient::generateSecuredApiKey(
                            '123412341234123412341243', // A search key that you keep private
                            [
                                'filters' => 'Foo:7',
                                'attributesToRetrieve' =>['Foo1','Foo2','Foo3','Foo4'],
                                ]
                            );
1 Like

Glad you got there. One point of clarification from a colleague:

You can use attributesToRetrieve in a query, and in fact this is the preferred way of reducing the number of attributes coming back from the search. My apologies for giving you bad advice here.

The definitive way to accomplish what you describe is a multi-index query, but using attributesToRetrieve to shape the payload for the second query. I’m sorry my advice forced a more complicated solution – hopefully putting this here will help the next person that finds this.

1 Like

You are right @chuck.meyer , I was just happy that I got it working, but now after some more thinking this should be the correct approach (I think) with a multi-index search query combined with attributesToRetrieve and only one search-box (=single query instead of two per search):

But the issue now is (as before), that I get twice the same result in both < ais-hits>, eventho the filters are different (searchClient1 vs. searchClient2). It’s probably not possible to add the second searchClient as prop to < ais-index> and with an additional < ais-configure> I can only define search parameters, but not a searchClient, if I understood the docs correctly.

So the initial searchClient in < ais-search> gets all the results for both < ais-hits> and with an additional < ais-configure> I can only filter these results.

<template>
  <div>
    <ais-instant-search
        :search-client="this.searchClient_1"  //first search settings (1)
        index-name="my_main_index"
      >
        <ais-search-box v-model="query" />

        <ais-hits>
          <template slot="item" slot-scope="{ item }">
            <h3><ais-highlight :hit="item" attribute="Typ" />{{ item.foo}}({{ item.bar}})</h3>
          </template>
        </ais-hits>

      <ais-index :search-client="searchClient_2" index-name="my_main_index"> //second search settings (2)

        <ais-hits>
          <template slot="item" slot-scope="{ item }">
            <h3><ais-highlight :hit="item" attribute="foo" />{{ item.foo}}({{ item.bar}})</h3>
          </template>
        </ais-hits>

     </ais-index>

    </ais-instant-search>
  </div>
</template>

And for the partial result (filter settings 2) I used attributesToRetrieve in the generateSecuredApiKey function:

$securedApiKey_store = \Algolia\AlgoliaSearch\SearchClient::generateSecuredApiKey(
                            '123412341234123412341243', // A search key that you keep private
                            [
                                'filters' => 'Foo:7',
                                'attributesToRetrieve' =>['Foo1','Foo2','Foo3','Foo4'],
                                ]
                            );