typesense / typesense-instantsearch-adapter

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

Typesense does not support cross-field ORs at the moment. The adapter could not OR values between these field #82

Open HananoshikaYomaru opened 2 years ago

HananoshikaYomaru commented 2 years ago

Description

Typesense does not support cross-field ORs at the moment. The adapter could not OR values between these field

This error is from SearchRequestAdapter.js. The error itself is self-descriptive, I just want to know why in this example, https://showcase-nextjs-typesense-ecommerce-store.vercel.app/ ,it is completely to use cross-field ORs.

error

Steps to reproduce

{
  "name": "sections",
  "fields": [
    {
      "name": "organization",
      "type": "string",
      "facet": true,
      "optional": false,
      "index": true
    },
    {
      "name": "course_code",
      "type": "string",
      "facet": false,
      "optional": false,
      "index": true
    },
    {
      "name": "course_title",
      "type": "string",
      "facet": false,
      "optional": false,
      "index": true
    },
    {
      "name": "students",
      "type": "string[]",
      "facet": false,
      "optional": false,
      "index": true
    },
    {
      "name": "instructors",
      "type": "string[]",
      "facet": false,
      "optional": false,
      "index": true
    },
    {
      "name": "num_students",
      "type": "int32",
      "facet": false,
      "optional": false,
      "index": true
    },
    {
      "name": "num_instructors",
      "type": "int32",
      "facet": false,
      "optional": false,
      "index": true
    },
    {
      "name": "created_at",
      "type": "string",
      "facet": false,
      "optional": false,
      "index": true
    },
    {
      "name": "updated_at",
      "type": "string",
      "facet": false,
      "optional": false,
      "index": true
    }
  ],
  "default_sorting_field": ""
}

This is the schema.

The error should not happen, just as https://showcase-nextjs-typesense-ecommerce-store.vercel.app/

Metadata

Typsense Version: 2.2.0

OS: ubuntu

HananoshikaYomaru commented 2 years ago

solved. The adapter use a regex to match facet filter internally. And the separator is :. Therefore I cannot : as my separator.

CLSnazel commented 1 year ago

Hi there!

Is it possible to reopen this issue? We are running into this error with customer provided strings which contain colons. We would like to avoid asking our customer to change them. In our case, the colons are not a separator, but a way of categorizing a name of an item in the collection in a human-readable way. Take for example the name of locations, where a colon is used following a neighborhood to categorize several grocery stores with the same name:

“Capitol Hill: Whole Food’s Market” “Belltown: Whole Food’s Market” “Roosevelt: Whole Food’s Market”

Similar to gif in the original comment, the RefinementList component is somewhat functioning with the colons when only one item with a colon is selected. When there is more than one item, and one of the items contains a colon the error appears.

With one item containing the colon, the adapter is sending the following filter string: location_name:Capitol Hill:=[' Whole Food's Market']. It does not resolve two colons unless they are both the same prefix leading up the first colon. For example, where both items have the prefix of “Capitol Hill”: location_name:Capitol Hill:=[' Whole Food's Market', ' QFC']

In both cases the adapter does not send the filters in quite the right syntax. We should be able to send a filter like location_name:=['Capitol Hill: Whole Food's Market', 'Capitol Hill: QFC', 'Belltown: Whole Food Market'] when using instantsearch components like RefinementList.

Seeing that colons are now supported in typesense filters as of v0.17.0, it is really cumbersome to not have the same support on this adapter. Can we please update the regex or logic that uses the regex to properly support colons in the filter values?

jasonbosco commented 1 year ago

Instantsearch internally generates filter strings in this format: facetName:facetValue when a refinementList widget is used. The adapter then parses that into facetName and facetValue components using a Regex and converts it into a Typesense filter_by string format with those parsed components.

The problem is that given a hypothetical string like facetName:with:colons:facetValue:with:colons, it's hard to know which part of this is the facetName and which is the facetValue. Currently the regex used in the adapter assumes that all characters before the last colon are part of the facetName, and characters after that are part of the facetValue.

In your case, it sounds like the facetValue component has colons, but not the facetName.

I just pushed out v2.7.0-2 of the adapter, where I've added a new parameter called facetableFieldsWithSpecialCharacters to help with your use-case. Could you update to this version, and then follow these instructions: https://github.com/typesense/typesense-instantsearch-adapter/blob/e7d4c34e1b58192d1797b8d1f560fc9706216e46/README.md#special-characters-in-field-names--values

CLSnazel commented 1 year ago

Thanks so much for the quick turnaround on this, Jason. I can confirm that this version of the adapter is working as expected with the new parameter. (Just for the colons in field values as we don’t currently have a use case for special characters in field names to test against at this time.)

While it appears to be behaving well with our current typesense server version of 0.24.0, we will likely hold off on upgrading the adapter to this version until there is an release of typesense 0.25.0 on the cloud to ensure everything plays nicely in a production environment.

jasonbosco commented 1 year ago

Awesome, thank you for confirming!

we will likely hold off on upgrading the adapter to this version until there is an release of typesense 0.25.0

I'm guessing this is based on the compatibility matrix in the README file of this repo, yeah? If so, it's a bit confusing... I meant to convey that if you're using Typesense 0.25.0.rc then you want to use 2.7.0-x of the adapter to take advantage of some of the latest features. But otherwise, 2.7.0-x of the adapter is fully compatible with 0.24.0 of Typesense (it has graceful fallbacks built-in). So it's safe to use this in production, especially since 0.25.0 of Typesense Server is still ways out.