typesense

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 7, 2021 License: Apache-2.0 Imports: 10 Imported by: 0

README

Typesense Go

An unofficial Go client for Typesense HTTP API.

GoDoc Go Report Card codecov Build Status

Installation

To install typesense-go using go modules just run the command below:

go get github.com/GianOrtiz/typesense-go

Usage

We will show you how to use this package to create a client, create a collection, index a document and search for documents. This usage section is inspired by the guide for other programming languages in the typesense website.

Before you can communicate with Typesense you need a client, to create a client you can use the following code:

client := typesense.NewClient(
  &typesense.Node{
    Host: "localhost",
    Port: "8108",
    Protocol: "http",
    APIKey: "api-key",
  },
  2,
)

if err := client.Ping(); err != nil {
  log.Printf("couldn't connect to typesense: %v", err)
}

Now you can define your collection and create it:

booksSchema := typesense.CollectionSchema{
  Name: "books",
  Fields: []typesense.CollectionField{
    {
      Name: "title",
      Type: "string",
    },
    {
      Name: "authors",
      Type: "string[]",
    },
    {
      Name: "image_url",
      Type: "string",
    },
    {
      Name: "publication_year",
      Type: "int32",
    },
    {
      Name: "ratings_count",
      Type: "int32",
    },
    {
      Name: "average_rating",
      Type: "int32",
    },
    {
      Name: "authors_facet",
      Type: "string[]",
      Facet: true,
    },
    {
      Name: "publication_year_facet",
      Type: "string",
      Facet: true,
    },
  },
  DefaultSortingField: "ratings_count",
}
collection, err := client.CreateCollection(booksSchema)
if err != nil {
  log.Printf("couldn't create collection books: %v", err)
}

Let's suppose we have a struct type Book that represents the document for the books collection:

type Book struct {
  Title string `json:"title"`
  Authors []string `json:"authors"`
  ImageURL string `json:"image_url"`
  PublicationYear int32 `json:"publication_year"`
  RatingsCount int32 `json:"ratings_count"`
  AverageRating float64 `json:"average_rating"`
  AuthorsFacet []string `json:"authors_facet"`
  PublicationYearFacet string `json:"publication_year_facet"`
}

We can create a new book document:

goProgrammingLanguage := Book{
  Title:                "The Go Programming Language",
  Authors:              []string{"Brian W. Kernighan", "Alan Donovan"},
  ImageURL:             "https://images-na.ssl-images-amazon.com/images/I/41aSIiETPPL.jpg",
  PublicationYear:      2015,
  RatingsCount:         287,
  AverageRating:        4.7,
  AuthorsFacet:         []string{"Brian W. Kernighan", "Alan Donovan"},
  PublicationYearFacet: "2015",
}
documentResponse := client.IndexDocument("books", goProgrammingLanguage)
if documentResponse.Error != nil {
  log.Printf("couldn't index book document: %v", err)
}

Now that we have a collection and a book document in the collection we can search for the book:

search, err := client.Search("books", "The Go Programming Language", []string{"title"}, nil)
if err != nil {
  log.Printf("couldn't search for books: %v", err)
}
for _, hit := range search.Hits {
  // hit.Document is a map[string]interface{}
  log.Println(hit.Document["title"])
}

Documentation

Overview

Package typesense is a Go client for Typesense, an open-source, typo tolerant search engine. This package defines a client and some useful methods to communicate with the Typesense API without the drawback of writing actual API requests.

Example

Example of an actual program that can connect to the Typesense API creates a new collection, index some document and retrieve it using search. Highly inspired by the official Typesense guide https://typesense.org/docs/0.11.2/guide/ .

// Get a client connection.
client := NewClient(
	&Node{
		Host:     "localhost",
		Port:     "8108",
		Protocol: "http",
		APIKey:   "api-key",
	},
	2,
)
if err := client.Ping(); err != nil {
	panic(err)
}

// Define your collection schema.
type Book struct {
	Title                string   `json:"title"`
	Authors              []string `json:"authors"`
	ImageURL             string   `json:"image_url"`
	PublicationYear      int32    `json:"publication_year"`
	RatingsCount         int32    `json:"ratings_count"`
	AverageRating        float64  `json:"average_rating"`
	AuthorsFacet         []string `json:"authors_facet"`
	PublicationYearFacet string   `json:"publication_year_facet"`
}
booksSchema := CollectionSchema{
	Name: "books",
	Fields: []CollectionField{
		{
			Name: "title",
			Type: "string",
		},
		{
			Name: "authors",
			Type: "string[]",
		},
		{
			Name: "image_url",
			Type: "string",
		},
		{
			Name: "publication_year",
			Type: "int32",
		},
		{
			Name: "ratings_count",
			Type: "int32",
		},
		{
			Name: "average_rating",
			Type: "int32",
		},
		{
			Name:  "authors_facet",
			Type:  "string[]",
			Facet: true,
		},
		{
			Name:  "publication_year_facet",
			Type:  "string",
			Facet: true,
		},
	},
	DefaultSortingField: "ratings_count",
}
if _, err := client.CreateCollection(booksSchema); err != nil {
	panic(err)
}

// Index a new book document.
goProgrammingLanguage := Book{
	Title:                "The Go Programming Language",
	Authors:              []string{"Brian W. Kernighan", "Alan Donovan"},
	ImageURL:             "https://images-na.ssl-images-amazon.com/images/I/41aSIiETPPL.jpg",
	PublicationYear:      2015,
	RatingsCount:         287,
	AverageRating:        4.7,
	AuthorsFacet:         []string{"Brian W. Kernighan", "Alan Donovan"},
	PublicationYearFacet: "2015",
}
documentResponse := client.IndexDocument("books", goProgrammingLanguage)
if documentResponse.Error != nil {
	panic(documentResponse.Error)
}

// Searches for the document by title and prints it.
search, err := client.Search("books", "The Go Programming Language", []string{"title"}, nil)
if err != nil {
	log.Printf("couldn't search for books: %v", err)
}
for _, hit := range search.Hits {
	log.Println(hit.Document["title"])
}
Output:

Index

Examples

Constants

View Source
const (
	// ActionDocumentsSearch allows only search requests.
	ActionDocumentsSearch = "documents:search"

	// ActionDocumentsGet allows fetching a single document.
	ActionDocumentsGet = "documents:get"

	// ActionCollectionsDelete allows a collection to be deleted.
	ActionCollectionsDelete = "collections:delete"

	// ActionCollectionsCreate allows a collection to be created.
	ActionCollectionsCreate = "collections:create"

	// ActionCollectionsAll allow all kinds of collection related operations.
	ActionCollectionsAll = "collections:*"

	// ActionAll Allows all operations.
	ActionAll = "*"
)

Variables

View Source
var ErrCollectionDuplicate = errors.New("a collection with this name already exists")

ErrCollectionDuplicate returned when the user tries to create a collection with a name that already exists.

View Source
var ErrCollectionFieldsRequired = errors.New("collection fields is required")

ErrCollectionFieldsRequired returned when the user tries to create a collection without its fields.

View Source
var ErrCollectionNameRequired = errors.New("collection name is required")

ErrCollectionNameRequired returned when the user tries to create a collection without a name.

View Source
var ErrCollectionNotFound = errors.New("collection was not found")

ErrCollectionNotFound returned when Typesense can't find the collection.

View Source
var ErrConnNotReady = errors.New("typesense connection is not ready")

ErrConnNotReady is the error that alerts that the connection with the Typesense API could not be established, it can be because of a connection timeout, a unauthorized response or a fail.

View Source
var ErrDuplicateID = errors.New("the document you are trying to index has an id that already exists in the collection")

ErrDuplicateID returned when the document the user is trying to index has an id that is already in the collection.

View Source
var ErrNotFound = errors.New("the resouce you are trying to fetch from Typesense does not exist")

ErrNotFound returned when no resource was found for the request.

View Source
var ErrQueryByRequired = errors.New("query by field is required")

ErrQueryByRequired returned when the user didn't specfify fields to query by, the url field `query_by` is a required field.

View Source
var ErrQueryRequired = errors.New("query field is required")

ErrQueryRequired returned when the user didn't specify a query to search for.

View Source
var ErrUnauthorized = errors.New("the api key does not match the Typesense api key")

ErrUnauthorized returned when the API key does not match the Typesense API key.

Functions

This section is empty.

Types

type APIError added in v0.2.1

type APIError struct {
	Message string `json:"message"`
}

APIError is an error returned from the API.

func (APIError) Error added in v0.2.1

func (e APIError) Error() string

Error returns a string representation of the error.

type APIKey added in v0.3.0

type APIKey struct {
	ID          int       `json:"id"`
	Value       string    `json:"value"`
	Description string    `json:"description,omitempty"`
	Actions     []string  `json:"actions"`
	Collections []string  `json:"collections"`
	ExpiresAt   time.Time `json:"expires_at,omitempty"`
}

APIKey is the model for a Typesense API key.

type APIResponse

type APIResponse struct {
	Message string `json:"message"`
}

APIResponse is the default API message response.

type Alias added in v0.3.0

type Alias struct {
	Name           string `json:"name,omitempty"`
	CollectionName string `json:"collection_name"`
}

Alias is the representation of a collection alias.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is the client to communicate with the Typesense API.

func NewClient

func NewClient(masterNode *Node, timeoutSeconds int, replicaNodes ...*Node) *Client

NewClient configures a client using the master node and timeout seconds.

func (*Client) CreateAPIKey added in v0.3.0

func (c *Client) CreateAPIKey(key APIKey) (*APIKey, error)

CreateAPIKey creates a new API key for the Typesense API.

func (*Client) CreateAlias added in v0.3.0

func (c *Client) CreateAlias(aliasName string, alias *Alias) (*Alias, error)

CreateAlias creates a new collection alias for a collection or updates the alias if it already exists.

func (*Client) CreateCollection

func (c *Client) CreateCollection(collectionSchema CollectionSchema) (*Collection, error)

CreateCollection creates a new collection using the given collection schema.

func (*Client) DebugInfo

func (c *Client) DebugInfo() (string, error)

DebugInfo retrieves the debug information from the Typesense API.

func (*Client) DeleteAPIKey added in v0.3.0

func (c *Client) DeleteAPIKey(id int) error

DeleteAPIKey deletes an API key by its id.

func (*Client) DeleteAlias added in v0.3.0

func (c *Client) DeleteAlias(aliasName string) (*Alias, error)

DeleteAlias deletes an alias by its name.

func (*Client) DeleteCollection

func (c *Client) DeleteCollection(collectionName string) (*Collection, error)

DeleteCollection deletes a collection by its name.

func (*Client) DeleteDocument

func (c *Client) DeleteDocument(collectionName, documentID string) *DocumentResponse

DeleteDocument deletes a document in the collection by its id.

func (*Client) GetAPIKey added in v0.3.0

func (c *Client) GetAPIKey(id int) (*APIKey, error)

GetAPIKey retrieves a Typesense API key by its id.

func (*Client) GetAPIKeys added in v0.3.0

func (c *Client) GetAPIKeys() ([]*APIKey, error)

GetAPIKeys retrieve all API keys.

func (*Client) Health

func (c *Client) Health() bool

Health checks the health information from the Typesense API.

func (*Client) IndexDocument

func (c *Client) IndexDocument(collectionName string, document interface{}) *DocumentResponse

IndexDocument index a new document in the collection.

func (*Client) Ping

func (c *Client) Ping() error

Ping checks if the client has a connection with the Typesense API.

func (*Client) RetrieveAlias added in v0.3.0

func (c *Client) RetrieveAlias(aliasName string) (*Alias, error)

RetrievesAlias retrieves an alias metadata by its name.

func (*Client) RetrieveAliases added in v0.3.0

func (c *Client) RetrieveAliases() ([]*Alias, error)

RetrieveAliases retrieve all aliases in Typesense.

func (*Client) RetrieveCollection

func (c *Client) RetrieveCollection(collectionName string) (*Collection, error)

RetrieveCollection retrieves a single collection by its name.

func (*Client) RetrieveCollections

func (c *Client) RetrieveCollections() ([]*Collection, error)

RetrieveCollections get all collections from Typesense.

func (*Client) RetrieveDocument

func (c *Client) RetrieveDocument(collectionName, documentID string) *DocumentResponse

RetrieveDocument retrieves a document in the collection by its id.

func (*Client) Search

func (c *Client) Search(collectionName, query string, queryBy []string, searchOptions *SearchOptions) (*SearchResponse, error)

Search searches for the query using the queryBy argument and other options in searchOptions in the Typesense API.

type Collection

type Collection struct {
	CollectionSchema
	NumDocuments int   `json:"num_documents"`
	CreatedAt    int64 `json:"created_at"`
}

Collection is the model of a collection created in the Typesense API.

type CollectionField

type CollectionField struct {
	Name  string `json:"name"`
	Type  string `json:"type"`
	Facet bool   `json:"facet"`
}

CollectionField is a Typesense collection field.

type CollectionSchema

type CollectionSchema struct {
	Name                string            `json:"name"`
	Fields              []CollectionField `json:"fields"`
	DefaultSortingField string            `json:"default_sorting_field"`
}

CollectionSchema is the definition of a collection schema to create in Typesense.

type DocumentResponse

type DocumentResponse struct {
	Data  []byte
	Error error
}

DocumentResponse is the response returned with a document. Because the document can't be retrieved immediatyl we wrap the data into this struct so it can be unmarshaled after.

func (*DocumentResponse) UnmarshalDocument

func (ds *DocumentResponse) UnmarshalDocument(document interface{}) error

UnmarshalDocument will unmarshal the document data into the given interface.

type FacetCount

type FacetCount struct {
	FieldName string `json:"field_name"`
	Counts    []struct {
		Count int    `json:"count"`
		Value string `json:"value"`
	} `json:"counts"`
}

FacetCount is the representation of a Typesense facet count.

type HTTPError added in v0.3.0

type HTTPError struct {
	Status       int    `json:"status"`
	ResponseBody []byte `json:"body"`
}

HTTPError returns an error when an unexpected response status code is received.

func (HTTPError) Error added in v0.3.0

func (e HTTPError) Error() string

type Node

type Node struct {
	// Host is the address of your Typesense host.
	Host string `json:"host"`

	// Port is the port Typesense is running on.
	Port string `json:"port"`

	// Protocol is the protocol Typesense is using(http, https)
	Protocol string `json:"protocol"`

	// APIKey is the Typesense API Key that will be set in X-Typesense-API-Key header.
	APIKey string `json:"apiKey"`
}

Node is a Typesense node, either the master or a read replica.

type SearchHighlight

type SearchHighlight struct {
	Field    string   `json:"field"`
	Snippet  string   `json:"snippet"`
	Snippets []string `json:"snippets"`
	Indices  []int    `json:"indices"`
}

SearchHighlight represents the highlight of texts in the search result.

type SearchOptions

type SearchOptions struct {
	// Query text to search for.
	Query string `url:"q"`

	// QueryBy represents fields to query_by.
	QueryBy []string

	// MaxHits is the max number of hits for the query search, value
	// increase may increase latency. Default value is 500.
	MaxHits *int

	// Prefix whether the query should be treated as a prefix or not.
	Prefix *bool

	// FilterBy represents filter conditions for refining your search
	// results.
	FilterBy []string

	// SortBy list of numerical values and their corresponding sort order
	// to sort results by.
	SortBy []string

	// FacetBy list of fields that will be used for faceting your results on.
	FacetBy []string

	// MaxFacetValues maximum number of facet values to be returned.
	MaxFacetValues *int

	// FacetQuery filter facet values by this paremeter, only values that
	// match the facet value will be matched.
	FacetQuery *string

	// NumTypos number of typographical errors (1 or 2) that would be
	// tolerated. Default value is 2.
	NumTypos *int

	// Page results from this specific page number would be fetched.
	Page *int

	// PerPage number of results to fetch per page. Default value is 10.
	PerPage *int

	// GroupBy aggregate search results by groups, groups must be a
	// facet field.
	GroupBy []string

	// GroupLimit maximum number of hits to return for every group
	// Default value is 3.
	GroupLimit *int

	// IncludeFields list of fields from the document to include in the search result.
	IncludeFields []string

	// ExcludeFields list of fields from the document to exclude in the search result.
	ExcludeFields []string

	// HighlightFullFields list of fields which should be highlighted fully without snippeting.
	// Default is all fields will be snipped.
	HighlightFullFields []string

	// SnippetThreshold Field values under this length will be fully highlighted, instead
	// of showing a snippet of relevant portion.
	// Default value is 30.
	SnippetThreshold *int

	// DropTokensThreshold if the number of hits is less than this value, Typesense
	// will try to drop tokens until the number of hits get to this value.
	// Default value is 10.
	DropTokensThreshold *int

	// TypoTokensThreshold if the number of results found for a specific query is less
	// than this number, Typesense will attempt to look for tokens with more typos
	// until enough results are found.
	// Default value is 100.
	TypoTokensThreshold *int

	// PinnedHits list of records to unconditionally include in the search results at
	// specific positions.
	PinnedHits []string

	// HiddenHits list of records to unconditionally hide from search results.
	Hiddenhits []string
}

SearchOptions is all options that will be used to create a form url encoded to search in Typesense. More information about the values can be found at https://typesense.org/docs/0.14.0/api/#search-collection.

type SearchResponse

type SearchResponse struct {
	FacetCounts []FacetCount      `json:"facet_counts"`
	Found       int               `json:"found"`
	Hits        []SearchResultHit `json:"hits"`
}

SearchResponse is the default Typesense response for a serch.

type SearchResultHit

type SearchResultHit struct {
	Highlights []SearchHighlight      `json:"highlights"`
	Document   map[string]interface{} `json:"document"`
}

SearchResultHit represents a Typesense search result hit. Every retrieved document from a search will have the type map[string]interface{}.

Directories

Path Synopsis
Package integration run integration tests.
Package integration run integration tests.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL