typesense / typesense-instantsearch-adapter

A JS adapter library to build rich search interfaces with Typesense and InstantSearch.js
MIT License
393 stars 63 forks source link

widgets not work for Multi-Index #133

Closed maxpanakov closed 1 year ago

maxpanakov commented 1 year ago

Description

Hey, i have a problem, when i applay refinementList(), it filter only by main index(collection)

Steps to reproduce

Code

import { debounce } from 'lodash';
import { connectHits } from 'instantsearch.js/es/connectors';
import instantsearch from 'instantsearch.js/es';
import {
  searchBox,
  pagination,
  refinementList,
  hits,
  stats,
  sortBy,
  hierarchicalMenu,
  rangeSlider,
  ratingMenu,
  toggleRefinement,
  hitsPerPage,
  clearRefinements,
  breadcrumb,
  index,
  configure,
} from 'instantsearch.js/es/widgets';
import TypesenseInstantSearchAdapter from 'typesense-instantsearch-adapter';
import { renderHits } from './hits';

let TYPESENSE_SERVER_CONFIG = {
  apiKey: process.env.TYPESENSE_SEARCH_ONLY_API_KEY, // Be sure to use an API key that only allows searches, in production
  nodes: [
    {
      host: process.env.TYPESENSE_HOST,
      port: process.env.TYPESENSE_PORT,
      protocol: process.env.TYPESENSE_PROTOCOL,
    },
  ],
  connectionTimeoutSeconds: 1,
  numRetries: 8,
};

const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter({
  server: TYPESENSE_SERVER_CONFIG,
  additionalSearchParameters: {
    query_by: 'title,description',
    query_by_weights: '4,1',
    num_typos: 1,
    typo_tokens_threshold: 1,
    exhaustive_search: true,
  },
  collectionSpecificSearchParameters: {
    products: {
      // facetFilters: ["categories:Loupes"]
      filter_by: "categories:=Loupes"
    },
    headlights: {
      // facetFilters: ["categories:Headlights"]
      filter_by: "categories:=Headlights"
    },
    accessories: {
      // facetFilters: ["categories:Accessories"]
      filter_by: "categories:=Accessories"
    },
  }
});
const searchClient = typesenseInstantsearchAdapter.searchClient;
const search = instantsearch({
  searchClient,
  indexName: 'products',
  routing: true,
});

const brands = refinementList({
  container: '#brand-list',
  attribute: 'brand',
  cssClasses: {
    searchableInput:
      'form-control form-control-sm form-control-secondary mb-2 border-light-2',
    searchableSubmit: 'd-none',
    searchableReset: 'd-none',
    showMore: 'btn btn-secondary btn-sm',
    list: 'list-unstyled',
    count: 'badge text-dark-2 ms-2',
    label: 'd-flex align-items-center',
    checkbox: 'me-2',
  },
})
const pag = pagination({
  container: '#pagination-Accessories',
  hitsPerPage: 1,
  cssClasses: {
    list: 'd-flex flex-row justify-content-end',
    item: 'px-2 d-block',
    link: 'text-decoration-none',
    disabledItem: 'text-muted',
    selectedItem: 'fw-bold text-primary',
  },
})
const hpp = hitsPerPage({
  container: '#hits-per-page',
  items: [
    { label: '3 per page', value: 1, default: true },
    { label: '18 per page', value: 18 },
  ],
  cssClasses: {
    select: 'form-select form-select-sm border-none text-black',
  },
})
const customHits = connectHits(
  renderHits
);
// ============ Begin Widget Configuration
search.addWidgets([
  customHits({ category: 'Loupes' }),
  pag,
  hpp,
  brands,
  index({ indexName: 'headlights' }).addWidgets([
    customHits({ category: 'Headlights' }),
  ]),
  index({ indexName: 'accessories' }).addWidgets([
    customHits({ category: 'Accessories' }),
  ]),

]);

window.sendEventDebounced = debounce((uiState) => {
  window.gtag('event', 'page_view', {
    page_path: window.location.pathname + window.location.search,
  });
}, 500);

search.use(() => ({
  onStateChange({ uiState }) {
    window.sendEventDebounced(uiState);
  },
  subscribe() { },
  unsubscribe() { },
}));

search.start();

Expected Behavior

Should filter in each index separately

Actual Behavior

Returns the same hits for each index, and ignores "collectionSpecificSearchParameters"

Metadata

Typesense Version: "instantsearch.js": "^4.38.1"

OS:

jasonbosco commented 1 year ago

For filter_by you want to use the configure widget, nested inside each index widget. Here's prior discussion about this: #17

maxpanakov commented 1 year ago

For filter_by you want to use the configure widget, nested inside each index widget. Here's prior discussion about this: #17

image in this case works the same way

maxpanakov commented 1 year ago

if u need to set filter like me just use

configure({
    disjunctiveFacetsRefinements: {
      categories: ['Loupes'],
    }
  }),

in configure