Skip to content

Commit a1e517c

Browse files
authored
feat(go): add bridge to transformation on search (#4924)
1 parent 3f4ab5b commit a1e517c

File tree

5 files changed

+153
-4
lines changed

5 files changed

+153
-4
lines changed

playground/go/search.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55

66
"github.com/algolia/algoliasearch-client-go/v4/algolia/search"
7+
// "github.com/algolia/algoliasearch-client-go/v4/algolia/transport"
78
)
89

910
func testSearch(appID, apiKey string) int {
@@ -23,6 +24,29 @@ func testSearch(appID, apiKey string) int {
2324
panic(err)
2425
}
2526

27+
// config := search.SearchConfiguration{
28+
// Configuration: transport.Configuration{
29+
// AppID: appID,
30+
// ApiKey: apiKey,
31+
// },
32+
// }
33+
//
34+
// config.WithTransformation("eu")
35+
//
36+
// fmt.Println(config.Transformation.Region)
37+
//
38+
// searchClient, err := search.NewClientWithConfig(config)
39+
// if err != nil {
40+
// panic(err)
41+
// }
42+
//
43+
// watchResponse, err := searchClient.SaveObjectsWithTransformation("foo", []map[string]any{{"objectID": "foobarbaz"}}, search.WithWaitForTasks(true))
44+
// if err != nil {
45+
// panic(err)
46+
// }
47+
//
48+
// fmt.Printf("%#v\n", watchResponse)
49+
2650
/*
2751
response, err := searchClient.AddOrUpdateObject(
2852
searchClient.NewApiAddOrUpdateObjectRequest(

templates/go/api.mustache

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"strings"
1212
{{#isSearchClient}}
1313
"github.com/algolia/algoliasearch-client-go/v4/algolia/errs"
14+
"github.com/algolia/algoliasearch-client-go/v4/algolia/ingestion"
1415
"cmp"
1516
"crypto/hmac"
1617
"crypto/sha256"

templates/go/client.mustache

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020

2121
"github.com/algolia/algoliasearch-client-go/v4/algolia/call"
2222
"github.com/algolia/algoliasearch-client-go/v4/algolia/compression"
23+
"github.com/algolia/algoliasearch-client-go/v4/algolia/ingestion"
2324
"github.com/algolia/algoliasearch-client-go/v4/algolia/transport"
2425
)
2526

@@ -29,6 +30,9 @@ type APIClient struct {
2930
appID string
3031
cfg *{{#lambda.titlecase}}{{#lambda.camelcase}}{{client}}{{/lambda.camelcase}}{{/lambda.titlecase}}Configuration
3132
transport *transport.Transport
33+
{{#isSearchClient}}
34+
ingestionTransporter *ingestion.APIClient
35+
{{/isSearchClient}}
3236
}
3337

3438
// NewClient creates a new API client with {{#hasRegionalHost}}appID, apiKey and region.{{/hasRegionalHost}}{{^hasRegionalHost}}appID and apiKey.{{/hasRegionalHost}}
@@ -72,13 +76,26 @@ func NewClientWithConfig(cfg {{#lambda.titlecase}}{{#lambda.camelcase}}{{client}
7276
cfg.WriteTimeout = {{x-timeouts.server.write}} * time.Millisecond
7377
}
7478

75-
return &APIClient{
79+
apiClient := APIClient{
7680
appID: cfg.AppID,
7781
cfg: &cfg,
7882
transport: transport.New(
79-
cfg.Configuration,
83+
cfg.Configuration,
8084
),
81-
}, nil
85+
}
86+
87+
{{#isSearchClient}}
88+
if cfg.Transformation != nil && cfg.Transformation.Region != "" {
89+
ingestionClient, err := ingestion.NewClient(apiClient.appID, cfg.ApiKey, cfg.Transformation.Region)
90+
if err != nil {
91+
return nil, err //nolint:wrapcheck
92+
}
93+
94+
apiClient.ingestionTransporter = ingestionClient
95+
}
96+
{{/isSearchClient}}
97+
98+
return &apiClient, nil
8299
}
83100

84101
{{#hasRegionalHost}}
@@ -375,4 +392,4 @@ func (a APIError) Is(target error) bool {
375392
_, ok := target.(*APIError)
376393
377394
return ok
378-
}
395+
}

templates/go/configuration.mustache

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package {{packageName}}
33

44
import (
55
"github.com/algolia/algoliasearch-client-go/v4/algolia/transport"
6+
"github.com/algolia/algoliasearch-client-go/v4/algolia/ingestion"
67
)
78

89
{{#hasRegionalHost}}
@@ -22,4 +23,20 @@ type {{#lambda.titlecase}}{{#lambda.camelcase}}{{client}}{{/lambda.camelcase}}{{
2223
transport.Configuration
2324
2425
{{#hasRegionalHost}}Region Region{{/hasRegionalHost}}
26+
{{#isSearchClient}}
27+
Transformation *TransformationConfiguration
28+
{{/isSearchClient}}
2529
}
30+
31+
{{#isSearchClient}}
32+
type TransformationConfiguration struct {
33+
Region ingestion.Region
34+
}
35+
36+
// WithTransformation sets the region of the current algolia application to the configuration, this is required to be called if you wish to leverage the transformation pipeline (via the *WithTransformation methods).
37+
func (s *SearchConfiguration) WithTransformation(region ingestion.Region) {
38+
s.Transformation = &TransformationConfiguration{
39+
Region: region,
40+
}
41+
}
42+
{{/isSearchClient}}

templates/go/search_helpers.mustache

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,4 +735,94 @@ func (c *APIClient) IndexExists(indexName string) (bool, error) {
735735
}
736736

737737
return false, err
738+
}
739+
740+
/*
741+
Helper: Similar to the `SaveObjects` method but requires a Push connector (https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/connectors/push/) to be created first, in order to transform records before indexing them to Algolia. The `region` must've been passed to the client's config at instantiation.
742+
743+
@param indexName string - the index name to save objects into.
744+
@param objects []map[string]any - List of objects to save.
745+
@param opts ...ChunkedBatchOption - Optional parameters for the request.
746+
@return []BatchResponse - List of batch responses.
747+
@return error - Error if any.
748+
*/
749+
func (c *APIClient) SaveObjectsWithTransformation(indexName string, objects []map[string]any, opts ...ChunkedBatchOption) (*ingestion.WatchResponse, error) {
750+
if c.ingestionTransporter == nil {
751+
return nil, reportError("`region` must be provided at client instantiation before calling this method.")
752+
}
753+
754+
var records []ingestion.PushTaskRecords
755+
756+
rawObjects, err := json.Marshal(objects)
757+
if err != nil {
758+
return nil, reportError("unable to marshal the given `objects`: %w", err)
759+
}
760+
761+
err = json.Unmarshal(rawObjects, &records)
762+
if err != nil {
763+
return nil, reportError("unable to unmarshal the given `objects` to an `[]ingestion.PushTaskRecords` payload: %w", err)
764+
}
765+
766+
return c.ingestionTransporter.Push( //nolint:wrapcheck
767+
c.ingestionTransporter.NewApiPushRequest(
768+
indexName,
769+
ingestion.NewEmptyPushTaskPayload().
770+
SetAction(ingestion.ACTION_ADD_OBJECT).
771+
SetRecords(records),
772+
),
773+
)
774+
}
775+
776+
/*
777+
Helper: Similar to the `PartialUpdateObjects` method but requires a Push connector (https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/connectors/push/) to be created first, in order to transform records before indexing them to Algolia. The `region` must've been passed to the client instantiation method.
778+
779+
@param indexName string - the index name to save objects into.
780+
@param objects []map[string]any - List of objects to save.
781+
@param opts ...ChunkedBatchOption - Optional parameters for the request.
782+
@return []BatchResponse - List of batch responses.
783+
@return error - Error if any.
784+
*/
785+
func (c *APIClient) PartialUpdateObjectsWithTransformation(indexName string, objects []map[string]any, opts ...PartialUpdateObjectsOption) (*ingestion.WatchResponse, error) {
786+
if c.ingestionTransporter == nil {
787+
return nil, reportError("`region` must be provided at client instantiation before calling this method.")
788+
}
789+
790+
791+
conf := config{
792+
headerParams: map[string]string{},
793+
createIfNotExists: true,
794+
}
795+
796+
for _, opt := range opts {
797+
opt.apply(&conf)
798+
}
799+
800+
var action ingestion.Action
801+
802+
if conf.createIfNotExists {
803+
action = ingestion.ACTION_PARTIAL_UPDATE_OBJECT
804+
} else {
805+
action = ingestion.ACTION_PARTIAL_UPDATE_OBJECT_NO_CREATE
806+
}
807+
808+
var records []ingestion.PushTaskRecords
809+
810+
rawObjects, err := json.Marshal(objects)
811+
if err != nil {
812+
return nil, reportError("unable to marshal the given `objects`: %w", err)
813+
}
814+
815+
err = json.Unmarshal(rawObjects, &records)
816+
if err != nil {
817+
return nil, reportError("unable to unmarshal the given `objects` to an `[]ingestion.PushTaskRecords` payload: %w", err)
818+
}
819+
820+
return c.ingestionTransporter.Push( //nolint:wrapcheck
821+
c.ingestionTransporter.NewApiPushRequest(
822+
indexName,
823+
ingestion.NewEmptyPushTaskPayload().
824+
SetAction(action).
825+
SetRecords(records),
826+
),
827+
)
738828
}

0 commit comments

Comments
 (0)