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

Vector Search Support #152

Open paul2302 opened 1 year ago

paul2302 commented 1 year ago

Is there a way to make vector search work with this repository and react instantsearch? I've looked into custom widgest by algolia and the federated search demo repo as it is at least using the multi search endpoint. I just couldn't find a way to make vector search work and after looking in the code, it seems it is not a permitted param for collectionSpecificSearchParameters.

Can you give me a hint on which level I would need to implement it or if this repo is the right place for it?

jasonbosco commented 1 year ago

Given that Algolia doesn't support vector search, Instantsearch does not expose any mechanism that triggers vector searches, so the adapter doesn't have anything to hook into.

So you would have to use the typesense-js client directly to do vector searches... For eg, have a look at the "Find Similar" link under each product in this demo. Here's how I trigger the vector search, outside the instantsearch lifecycle.

paul2302 commented 1 year ago

Thanks for the quick answer!

So if I wanted to use vector search and filter in parallel with filter widgets and sort by widget, I wont be able to use instantsearch, right?

jasonbosco commented 1 year ago

So if I wanted to use vector search and filter in parallel with filter widgets and sort by widget, I wont be able to use instantsearch, right?

I haven't explored Instantsearch's custom widgets enough to be able to answer this question confidently unfortunately.

If you're able to build a custom widget that somehow calls the typesense-js library directly and then updates the internal instantsearch state based on the response you get... may be? I'm not sure if this is possible or how complex it is to pull off.

paul2302 commented 1 year ago

Okay, thanks for your time. I was hoping I could simply add vector search to the collectionSpecificSearchParameters and it would work. I'm not quite sure how your adapter translates those params or if theres a way to pass params to typesense directly via the adapter as some comments suggested it (at least thats how I understood it).

jasonbosco commented 1 year ago

Adding vector_query to collectionSpecificSearchParameters is easy - but then that parameter will get sent to Typesense on all searches initiated by instantsearch... I'd imagine you'd want vector_query to be dynamic based on some user input?

paul2302 commented 1 year ago

No, I want to have a static vector query for each page load. We basically use a data object that implies a certain search (filter and vector) and then filterRefinement widgets. But the vector search only changes with another (different) page load (different data object loaded). Would that be possible? I guess even if it was possible it would be a misleading addition to your repo, right?

jasonbosco commented 1 year ago

If that solves for your use-case, happy to add vector_query to collectionSpecificSearchParameters - we anyway try to keep all parameters that can be used inside that config, in sync with all the search parameters available in typesense-js and let users decide which ones to use.

I'll push out a new ~rc~ release shortly with this.

jasonbosco commented 1 year ago

Could you update to v2.6.0 of the adapter and give it a shot now? You should be able to now set vector_query in collectionSpecificSearchParameters.

pixelkoduje commented 1 year ago

I would add to the schema of the document: forVectorize: ["keywords", "name", "description"] then typesense on adding documents would automatically vectorize the documents by adding some variable to the document.

And by what you could search for a document similar to this. client.index('products').similar(*1).limit(8)

*1 - id or the whole document, or a variable with a vector (neither)

paul2302 commented 1 year ago

@jasonbosco I do see the vector_query param. It might take a while until I can fully test it, but I will make sure to let you know, if it works how I hoped it would :)

paul2302 commented 1 year ago

Before I finished implementing it, I realized the available vector similariy function is not what I was looking for. I have a model A which contains a set of attributes and a model B which also contains the same type of attributes. I want to match them in a way that I look for A's that have the same values as B where B has values and I want to discard any differences that come from values that A has but B doesn't.

From a vector perspective:

A1: [1 ,0 ,1] A2: [1 ,1 ,1]

should match equally to

B: [1,0,1]

With the distance being 0 here. The function would be:

for each dimension:
 di = Math.max(Bi - Ai, 0)

Using cosine similarity would result in vector A1 matching better. For more complex vectors that can even mean that a vector gets preferred even if it matches worse.

However this is probably not a discussion for this repo.

From my perspective you can close that issue as the parameter vector_query is known now :)

Thanks for implementing the parameter, I really appreciate the work and typesense as an easy to setup search engine!

jasonbosco commented 1 year ago

If anyone's looking to implement semantic search with Typesense's vector search feature + Instantsearch.js UI, here's how: https://github.com/typesense/typesense-instantsearch-adapter#vector-search

snk5000 commented 1 year ago

@jasonbosco hi, are there any ways to implement the same vector search with embedding from query string in React instant search?