dekimir / postgres-searchbox

Enables react-instantsearch to work directly on PostgreSQL tables
Other
14 stars 1 forks source link

Discussion: highlight #8

Open data-envoy opened 1 year ago

data-envoy commented 1 year ago

There's some interesting things related to how highlighting works with Postgres vs Algolina ( instantsearch.js maintainers ).

With a search for 'siy blacc yello' on an algolia sandbox. You get a return object like this:

  _highlightResult: {
    name: {
      value:
        'WebRC - XDrone __ais-highlight__Spy__/ais-highlight__ Quadcopter -' + 
        ' __ais-highlight__Yello__/ais-highlight__w/__ais-highlight__Black__/ais-highlight__',
      matchLevel: 'full',
      fullyHighlighted: false,
      matchedWords: ['siy', 'blacc', 'yello'],
    },
    description: {
      value:
        'Record video from the air with this XDrone __ais-highlight__Spy__/ais-highlight__. ' + 
        'You can navigate it indoors or...',
      matchLevel: 'partial',
      fullyHighlighted: false,
      matchedWords: ['siy'],
    },
  },

Algolia wraps the matched words in __ais-highlight__ and also returns an array of matchedWords.

I guess the matchedWords are useful in UI incase the user wants to delete them from the query.


Now, with postgres we can highlight the matched words fine by using ts_headline. But PG doesn't have anything out of the box like algolina's matchedWords.

So, we need to work on that at application level.

For an example search in the movies dataset of 'tests fires OR xyz' the first seach result has a highlight string like:

__ais-highlight__Tested__/ais-highlight__ by __ais-highlight__Fire__/ais-highlight__

we know the search query. And can extract the highlighted words as anything wrapped in __ais-highlight__.

queryWords = [ 'tests', 'fires', 'xyz' ];
highlightedWords = ['Tested', 'Fire'];

How do we reliably derive matchedWords from what we know? So that we can return something like:

_highlightResult: {
  primarytitle: {
    value:
      '__ais-highlight__Tested__/ais-highlight__ by __ais-highlight__Fire__/ais-highlight__',
    matchLevel: 'full',
    fullyHighlighted: false,
    matchedWords: [ 'tests', 'fires' ],
  },
},

Currently leaving matched words as [], the <Highlight> component does work. Custom/other code that relies on the matchedWords, ( and also matchLevel, fullyHighlighted ) would fail.

For now, I have to leave this as it is and try and tackle facet searching.