typesense-go icon indicating copy to clipboard operation
typesense-go copied to clipboard

Add support for generics

Open Hades32 opened this issue 11 months ago • 2 comments

Search results are untyped (map[string]any) which makes this very unergonomic to use

Currently we're working around it with a custom search method

func searchCollection[TDoc any](ctx context.Context, collection string, params *api.SearchCollectionParams) (*Result[TDoc], error) {
	resp, err := typesenseApiClient.SearchCollection(ctx, collection, params)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	if resp.StatusCode > 299 {
		return nil, utils.ErrHighStatusCode
	}
	var results Result[TDoc]
	err = json.NewDecoder(resp.Body).Decode(&results)
	if err != nil {
		return nil, err
	}
	return &results, nil
}

and matching types

type  Result[TDoc any] struct {
	GroupedHits []GroupedHit[TDoc] `json:"grouped_hits,omitempty"`
	Hits []*ResultHit[TDoc] `json:"hits,omitempty"`
...

Hades32 avatar Aug 16 '23 09:08 Hades32

@Hades32 The way you are doing it is the only way possible, it wouldn't be possible to use generics using the methods from this library (for example something like client.Collection("companies").Documents().Search[Company](searchParameters)), because Go does not allow parametrized methods.

The only way would be to set the result type at client creation, but then that client is effectively bound to one index only. Or well, provide a convenience function like you did.

Another way would be to allow you to provide a pointer to the result struct that you want to unmarshall the result into - the signature for that argument in the Search function would simply be interface{}, so this wouldn't even require generics.

tadejsv avatar Nov 06 '23 11:11 tadejsv

Happy to accept a PR with any helper / utility functions that help with usability.

kishorenc avatar Nov 06 '23 15:11 kishorenc