How is Facets Refinements Rendered in the algolia dashboard?

Hello,

I believe that algolia dashboard now uses react-instantsearch to render the UI. I wanted to know how are you able to render all the facets as mentioned in attributes for Faceting?

Since I am not sure how is the list of refinements fetched from the settings without making an additional query.

I have a very similar use case and currently I am trying to nest two Instances to make it work.

@marielaure.thuret

Hi @harshmaur,

You’re correct: we’re using react-instantsearch on the “Browse” tab, while on the other tabs we’re using custom React components with Redux for state management.

Just to be clear, is the list that you mention this one?

If this is the case, we are displaying suggestions by actually using a sample of results with an empty query and extracting the attributes to suggest by using the following function:

export const getSampleAttributes = createSelector(
  (state: State) => state.explorerBrowseManager.sampleResponse,
    sampleResponse => {
      if (!isReady(sampleResponse)) {
        return eventual();
      }

      return sortBy(
        union(...sampleResponse.hits.map(record => extractKeys(record))).filter(
          x => x !== 'objectID'
        )
     );
   }
);

Long story short: we’re not using react-instantsearch for this section, but we’re using a sample of hits to build the “attributes for faceting” list.

Let me know if you need more details and if this helps you out!

Cheers

Edit

I think you’re referring to how we generate dynamically the facets menu in the browse tab:

In this case we’re doing something similar: getting the facets from the sample response and using it to loop N FacetMenu components:

export const getSampleFacets = createSelector(
  (state: State) => state.explorerBrowseManager.sampleResponse,
  sampleResponse => {
    if (!isReady(sampleResponse)) {
      return eventual();
    }

    return sampleResponse.facets;
  }
);

Therefore we pass this list of facets down to the left menu component:

...
{this.props.sampleFacetList.map((x: string, i: number) =>
  <FacetsMenu
     title={x}
     key={i}
     id={x}
     facetName={x}
     isSearchable={this.isFacetSearchable(x)}
     algoliaClientIndex={this.props.algoliaClientIndex}
  />)}

Hope it helps, let me know if you have more questions about it.

Hi,

Thank you for answering the question, No, I am not referring to this section. I am only referring to the “Browse” section, if you see, on the left there are widgets which I can use to refine the values, I see that those are generated automatically, I believe there is a customConnector applied there.

Now as per the RefinementList API, we have to provide the attributeName to be able to render the list.

CloudApp

Check the widget on the left.

However I have 200 items in my attribute to facets and I am not sure how did the left widgets got generated dynamically, without making an additional query.

I hope I made more sense this time.

Oh Okay, you just answered it. Umm Its not making a clear sense to me, I have never used createSelector. is that from recompose library?

Indeed, we’re using just to optimize / cache our redux state properties.

In this case it’s not the important part, at the end what you’d need it’s just a list of facets like this one:

const facetList = ['name', 'brand'];

After you get this list, you can render N instances of react-instansearch’s menu component (https://community.algolia.com/react-instantsearch/widgets/Menu.html):

facetList.map(facet => <Menu attributeName={facet}>

The final part is how we’re getting facetList. In order to do that, we run an empty query by using our Algolia JS client and storing the facets result in our state:

const facetList = [];
const client = algoliasearch('app-id', 'api-key');
const index = client.initIndex('currentIndex');

index.search('').then(result => {
  // store the response facet values inside our state
  facetList = Object.keys(results.facets);
});

Does this makes sense to you?

1 Like

So infact there is a second query happening!

So I was trying to implement an already filtered state, and show available facets from it. I wondered if something was happening behind the scenes to make it happen without making additional query.

Yes, unfortunately there’s no simple way to achieve this without an additional query, but @marielaure.thuret could prove me wrong :slight_smile:

The Algolia JS client code worked great for me and now its much faster and cleaner than what I had done before.

1 Like

Hi,

So I’m trying to implement this in my react-instasearch app. But it’s not returning results.facets.

Here what I have:

  • I installed react instaSearch (yarn add react-instantsearch)
  • installed @types/algoliasearch
  • this is my package.json file:
  "dependencies": {
    "@types/algoliasearch": "^3.24.9",
    "react": "^16.2.0",
    "react-dom": "^16.2.0",
    "react-instantsearch": "^5.0.1",
    "react-scripts": "1.1.1"
  },

and I’m trying to do:

import * as algoliasearch from 'algoliasearch';

        let facetList = [];
        const client = algoliasearch('xxx', 'xxx');
        const index = client.initIndex('products');

        index.search('').then(result => {
            console.log(result);
        });

but the problem is that in the example results (which is mistake btw) have property facets. And I don’t have it :frowning:
It’s not even support in typings. So my question is how can I get the facets list?

Does this help you Dominik, or did you find a solution meanwhile?