Go client for the Typesense API: https://github.com/typesense/typesense
go get github.com/typesense/typesense-go
Import the the package into your code :
import "github.com/phiHero/typesense-go-ex/v2/typesense"
Create new client:
client := typesense.NewClient(
typesense.WithServer("http://localhost:8108"),
typesense.WithAPIKey("<API_KEY>"))
New client with advanced configuration options (see godoc):
client := typesense.NewClient(
typesense.WithServer("http://localhost:8108"),
typesense.WithAPIKey("<API_KEY>"),
typesense.WithConnectionTimeout(5*time.Second),
typesense.WithCircuitBreakerMaxRequests(50),
typesense.WithCircuitBreakerInterval(2*time.Minute),
typesense.WithCircuitBreakerTimeout(1*time.Minute),
)
New client with multi-node configuration options:
client := typesense.NewClient(
typesense.WithNearestNode("https://xxx.a1.typesense.net:443"),
typesense.WithNodes([]string{
"https://xxx-1.a1.typesense.net:443",
"https://xxx-2.a1.typesense.net:443",
"https://xxx-3.a1.typesense.net:443",
}),
typesense.WithAPIKey("<API_KEY>"),
typesense.WithNumRetries(5),
typesense.WithRetryInterval(1*time.Second),
typesense.WithHealthcheckInterval(2*time.Minute),
)
You can also find some examples in integration tests.
schema := &api.CollectionSchema{
Name: "companies",
Fields: []api.Field{
{
Name: "company_name",
Type: "string",
},
{
Name: "num_employees",
Type: "int32",
},
{
Name: "country",
Type: "string",
Facet: true,
},
},
DefaultSortingField: pointer.String("num_employees"),
}
client.Collections().Create(context.Background(), schema)
In v2.0.0
+, the client allows you to define a document struct to be used type for some of the document operations.
To do that, you've to use typesense.GenericCollection
:
type companyDocument struct {
ID string `json:"id"`
CompanyName string `json:"company_name"`
NumEmployees int `json:"num_employees"`
Country string `json:"country"`
}
// doc is a typed document
doc, err := typesense.GenericCollection[*companyDocument](typesenseClient, collectionName).Document("123").Retrieve(context.Background())
document := struct {
ID string `json:"id"`
CompanyName string `json:"company_name"`
NumEmployees int `json:"num_employees"`
Country string `json:"country"`
}{
ID: "123",
CompanyName: "Stark Industries",
NumEmployees: 5215,
Country: "USA",
}
client.Collection("companies").Documents().Create(context.Background(), document)
newDocument := struct {
ID string `json:"id"`
CompanyName string `json:"company_name"`
NumEmployees int `json:"num_employees"`
Country string `json:"country"`
}{
ID: "123",
CompanyName: "Stark Industries",
NumEmployees: 5215,
Country: "USA",
}
client.Collection("companies").Documents().Upsert(context.Background(), newDocument)
searchParameters := &api.SearchCollectionParams{
Q: pointer.String("stark"),
QueryBy: pointer.String("company_name"),
FilterBy: pointer.String("num_employees:>100"),
SortBy: &([]string{"num_employees:desc"}),
}
client.Collection("companies").Documents().Search(context.Background(), searchParameters)
for the supporting multiple QueryBy
params, you can add ,
after each field
searchParameters := &api.SearchCollectionParams{
Q: pointer.String("stark"),
QueryBy: pointer.String("company_name, country"),
FilterBy: pointer.String("num_employees:>100"),
SortBy: &([]string{"num_employees:desc"}),
}
client.Collection("companies").Documents().Search(context.Background(), searchParameters)
client.Collection("companies").Document("123").Retrieve(context.Background())
document := struct {
CompanyName string `json:"company_name"`
NumEmployees int `json:"num_employees"`
}{
CompanyName: "Stark Industries",
NumEmployees: 5500,
}
client.Collection("companies").Document("123").Update(context.Background(), document)
client.Collection("companies").Document("123").Delete(context.Background())
filter := &api.DeleteDocumentsParams{FilterBy: "num_employees:>100", BatchSize: 100}
client.Collection("companies").Documents().Delete(context.Background(), filter)
client.Collection("companies").Retrieve(context.Background())
client.Collection("companies").Documents().Export(context.Background())
The documents to be imported can be either an array of document objects or be formatted as a newline delimited JSON string (see JSONL).
Import an array of documents:
documents := []interface{}{
struct {
ID string `json:"id"`
CompanyName string `json:"companyName"`
NumEmployees int `json:"numEmployees"`
Country string `json:"country"`
}{
ID: "123",
CompanyName: "Stark Industries",
NumEmployees: 5215,
Country: "USA",
},
}
params := &api.ImportDocumentsParams{
Action: pointer.String("create"),
BatchSize: pointer.Int(40),
}
client.Collection("companies").Documents().Import(context.Background(), documents, params)
Import a JSONL file:
params := &api.ImportDocumentsParams{
Action: pointer.String("create"),
BatchSize: pointer.Int(40),
}
importBody, err := os.Open("documents.jsonl")
// defer close, error handling ...
client.Collection("companies").Documents().ImportJsonl(context.Background(), importBody, params)
client.Collections().Retrieve(context.Background())
client.Collection("companies").Delete(context.Background())
keySchema := &api.ApiKeySchema{
Description: "Search-only key.",
Actions: []string{"documents:search"},
Collections: []string{"companies"},
ExpiresAt: time.Now().AddDate(0, 6, 0).Unix(),
}
client.Keys().Create(context.Background(), keySchema)
client.Key(1).Retrieve(context.Background())
client.Keys().Retrieve(context.Background())
client.Key(1).Delete(context.Background())
override := &api.SearchOverrideSchema{
Rule: api.SearchOverrideRule{
Query: "apple",
Match: "exact",
},
Includes: []api.SearchOverrideInclude{
{
Id: "422",
Position: 1,
},
{
Id: "54",
Position: 2,
},
},
Excludes: []api.SearchOverrideExclude{
{
Id: "287",
},
},
}
client.Collection("companies").Overrides().Upsert(context.Background(), "customize-apple", override)
client.Collection("companies").Overrides().Retrieve(context.Background())
client.Collection("companies").Override("customize-apple").Delete(context.Background())
body := &api.CollectionAliasSchema{CollectionName: "companies_june11"}
client.Aliases().Upsert("companies", body)
client.Alias("companies").Retrieve(context.Background())
client.Aliases().Retrieve(context.Background())
client.Alias("companies").Delete(context.Background())
synonym := &api.SearchSynonymSchema{
Synonyms: []string{"blazer", "coat", "jacket"},
}
client.Collection("products").Synonyms().Upsert(context.Background(), "coat-synonyms", synonym)
synonym := &api.SearchSynonymSchema{
Root: "blazer",
Synonyms: []string{"blazer", "coat", "jacket"},
}
client.Collection("products").Synonyms().Upsert(context.Background(), "coat-synonyms", synonym)
client.Collection("products").Synonym("coat-synonyms").Retrieve(context.Background())
client.Collection("products").Synonyms().Retrieve(context.Background())
client.Collection("products").Synonym("coat-synonyms").Delete(context.Background())
preset := &api.PresetUpsertSchema{}
preset.Value.FromMultiSearchSearchesParameter(api.MultiSearchSearchesParameter{
Searches: []api.MultiSearchCollectionParameters{
{
Collection: "books",
},
},
})
// or: preset.Value.FromSearchParameters(api.SearchParameters{Q: "Books"})
client.Presets().Upsert(context.Background(), "listing-view-preset", preset)
client.Preset("listing-view-preset").Retrieve(context.Background())
client.Presets().Retrieve(context.Background())
client.Preset("listing-view-preset").Delete(context.Background())
client.Operations().Snapshot(context.Background(), "/tmp/typesense-data-snapshot")
client.Operations().Vote(context.Background())
Bug reports and pull requests are welcome on GitHub at https://github.com/typesense/typesense-go.
Install dependencies,
go mod download
Update the generated files,
go generate ./...
typesense-go
is distributed under the Apache 2 license.