The official Search.io Go client library.
Search.io offers a search and discovery service with Neuralsearch®, the world's first instant AI search technology. Businesses of all sizes use Search.io to build site search and discovery solutions that maximize e-commerce revenue, optimize on-site customer experience, and scale their online presence.
Requires Go version 1.13 or higher.
Install sdk-go
with:
go get -u code.sajari.com/sdk-go
Then, import it using:
import "code.sajari.com/sdk-go"
Below are a few simple examples that will help get you up and running.
To start you need to create a client to make calls to the API.
You can get your account ID, collection ID, key ID and key secret from the Search.io console.
creds := sajari.KeyCredentials("key-id", "key-secret")
client, err := sajari.New("account_id", "collection_id", sajari.WithCredentials(creds))
if err != nil {
// handle
}
defer client.Close()
Note: do not forget to close the client when you are finished with it.
If you need to override the default endpoint, you can use the WithEndpoint
client option.
opts := []sajari.Opt{
sajari.WithEndpoint("api-au-valkyrie.sajari.com:50051"),
sajari.WithCredentials(sajari.KeyCredentials("key-id", "key-secret")),
}
client, err := sajari.New(shop.AccountID, shop.CollectionID, opts...)
if err != nil {
// handle
}
defer client.Close()
The endpoints that you can pass to WithEndpoint
include:
api-au-valkyrie.sajari.com:50051
api-us-valkyrie.sajari.com:50051
A record can be added to a collection using the CreateRecord
method on a record Pipeline
.
First, you should initialise the record pipeline by passing in its name and the version you want to use.
pipeline := client.Pipeline("record", "v5")
Next, set up any values that you need to pass to the record pipeline, define your record and call CreateRecord
.
Values allow you to control the pipeline execution. For example, they can be used to dynamically turn pipeline steps on or off and control how the record is processed.
values := map[string]string{
// ...
}
record := sajari.Record{
"id": 12345,
"name": "Smart TV",
"brand": "Sunny",
"price": 999,
}
key, _, err := pipeline.CreateRecord(context.Background(), values, record)
if err != nil {
// handle
}
You can use the returned key to uniquely identify the newly inserted record. This can be used in various calls such as GetRecord
, MutateRecord
, DeleteRecord
and ReplaceRecord
.
An existing record in your collection can be retrieved using the GetRecord
method on your Client
.
key := sajari.NewKey("id", "12345") // or using your Key returned from another call
record, err := client.GetRecord(context.Background(), key)
if err != nil {
// handle
}
An existing record in your collection can be entirely replaced using the ReplaceRecord
method on a record Pipeline
.
When calling ReplaceRecord
Search.io actually performs an upsert. If the record is an existing record, Search.io performs a diff between the old and new records and applies your changes—this is extremely efficient. Because ReplaceRecord
can both insert and update it is typically preferred over CreateRecord
when adding a record.
Note: if you want to make granular changes to the record it is best to use
MutateRecord
.
Note: if you want to change an indexed field you will need to use
ReplaceRecord
.
First, you should initialise the record pipeline by passing in its name and the version you want to use.
pipeline := client.Pipeline("record", "v5")
Next, set up any values that you need to pass to the record pipeline, define your record and call ReplaceRecord
.
Values allow you to control the pipeline execution. For example, they can be used to dynamically turn pipeline steps on or off and control how the record is processed.
values := map[string]string{
// ...
}
key := sajari.NewKey("id", "12345") // or using your Key returned from another call
record := sajari.Record{
"id": 12345,
"name": "Large Smart TV",
"brand": "Sunny",
"price": 999,
}
key, _, err = pipeline.ReplaceRecord(context.Background(), values, key, record)
if err != nil {
// handle
}
An existing record in your collection can be mutated using the MutateRecord
method on your Client
. You might need this method if you need to update a single field or unset a single field.
As an example, if you were storing products in your collection and you needed to update a product's price or stock levels this method would be useful.
Note: if you want to replace the entire record it is best to use
ReplaceRecord
.
Note: if you want to change an indexed field you will need to use
ReplaceRecord
.
You will need to pass one or more mutation operations to MutateRecord
that will be appled to your record. For example, you can pass an operation to set a field, unset a field or set multiple fields at once.
key := sajari.NewKey("id", "12345") // or using your Key returned from another call
// update a single field
err := client.MutateRecord(context.Background(), key, sajari.SetFieldValue("updated_at", time.Now().String()))
if err != nil {
// handle
}
// unset a single field
err := client.MutateRecord(context.Background(), key, sajari.SetFieldValue("available", nil))
if err != nil {
// handle
}
// set multiple fields at once
err := client.MutateRecord(context.Background(), key, sajari.SetFields(map[string]interface{}{
"updated_at": time.Now().String(),
"available": nil,
})...)
if err != nil {
// handle
}
An existing record in your collection can be deleted using the DeleteRecord
method on your Client
.
key := sajari.NewKey("id", "12345") // or using your Key returned from another call
err := client.DeleteRecord(context.Background(), key)
if err != nil {
// handle
}
You can search for records in your collection using the Search
method with a query Pipeline
.
First, you should initialise the query pipeline by passing in its name and the version you want to use.
pipeline := client.Pipeline("search", "v5")
Next, set up any values that you need to pass to the query pipeline, create a session and run your search.
Values allow you to control the pipeline execution. For example, they can be used to dynamically turn pipeline steps on or off and control how the records are processed.
In the example below, passing the
resultsPerPage
andpage
values allows you to paginate through records for the search query provided inq
. Note: this assumes that you have thepagination
step in your query pipeline.
values := map[string]string{
"q": "your search terms",
"resultsPerPage": "10",
"page": "1",
}
res, _, err := pipeline.Search(context.Background(), values, sajari.NonTrackedSession())
if err != nil {
// handle
}
for _, r := range res.Results {
log.Printf("Values: %v", r.Values)
log.Printf("Tokens: %v", r.Tokens)
}
If you don't want tracking enabled, then use NonTrackedSession
. For example your Search
call might look like:
res, _, err := pipeline.Search(context.Background(), values, sajari.NonTrackedSession())
if err != nil {
// handle
}
If you're tracking website-style searches, then use WebSearchSession
. For example your Search
call might look like:
res, _, err := pipeline.Search(context.Background(), values, sajari.WebSearchSession("q", sajari.NewSession()))
if err != nil {
// handle
}
If you want to manage the details of tracking externally, use Tracking
. For example your Search
call might look like:
res, _, err := pipeline.Search(context.Background(), values, sajari.Tracking{
Type: sajari.TrackingPosNeg,
QueryID: "4216691599",
Sequence: 1,
Field: "id",
Data: map[string]string{},
})
if err != nil {
// handle
}
Pull requests from the community are welcome. If you submit one, please keep the following guidelines in mind:
- Code must be
go fmt
compliant. - All types, structs and funcs should be documented.
- Ensure that
go test ./...
succeeds.
Run all tests:
go test ./...
We use the MIT License.