Skip to content

Commit 92b1ab7

Browse files
Merge #580
580: Feat Language settings & search parameter r=curquiza a=Ja7ad # Pull Request ## Related issue Fixes #575 ## What does this PR do? - Add language settings and search parameter ## PR checklist Please check if your PR fulfills the following requirements: - [x] Does this PR fix an existing issue, or have you listed the changes applied in the PR description (and why they are needed)? - [x] Have you read the contributing guidelines? - [x] Have you made sure that the title is accurate and descriptive of the changes? Thank you so much for contributing to Meilisearch! Co-authored-by: Javad <[email protected]>
2 parents 1cd56a5 + 63cf6b8 commit 92b1ab7

10 files changed

+928
-480
lines changed

.code-samples.meilisearch.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,3 +939,15 @@ update_proximity_precision_settings_1: |-
939939
client.Index("books").UpdateProximityPrecision(ByAttribute)
940940
reset_proximity_precision_settings_1: |-
941941
client.Index("books").ResetProximityPrecision()
942+
search_parameter_reference_locales_1: |-
943+
client.index("INDEX_NAME").Search("進撃の巨人", &meilisearch.SearchRequest{
944+
Locates: []string{"jpn"}
945+
})
946+
get_localized_attribute_settings_1: |-
947+
client.index("INDEX_NAME").GetLocalizedAttributes()
948+
update_localized_attribute_settings_1: |-
949+
client.index("INDEX_NAME").UpdateLocalizedAttributes([]*LocalizedAttributes{
950+
{ AttributePatterns: ["*_ja"], Locales: ["jpn"] },
951+
})
952+
reset_localized_attribute_settings_1: |-
953+
client.index("INDEX_NAME").ResetLocalizedAttributes()

client.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,11 @@ func (c *client) handleResponse(req *internalRequest, body []byte, internalError
244244
} else {
245245
internalError.ResponseToString = string(body)
246246

247+
if internalError.ResponseToString == nullBody {
248+
req.withResponse = nil
249+
return nil
250+
}
251+
247252
var err error
248253
if resp, ok := req.withResponse.(json.Unmarshaler); ok {
249254
err = resp.UnmarshalJSON(body)

client_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ func TestExecuteRequest(t *testing.T) {
7777
msg := []byte(`{"message":"post successful"}`)
7878
_, _ = w.Write(msg)
7979

80+
} else if r.Method == http.MethodGet && r.URL.Path == "/test-null-body" {
81+
w.WriteHeader(http.StatusOK)
82+
msg := []byte(`null`)
83+
_, _ = w.Write(msg)
8084
} else if r.Method == http.MethodPost && r.URL.Path == "/test-post-encoding" {
8185
w.WriteHeader(http.StatusCreated)
8286
msg := []byte(`{"message":"post successful"}`)
@@ -236,6 +240,18 @@ func TestExecuteRequest(t *testing.T) {
236240
expectedResp: nil,
237241
wantErr: false,
238242
},
243+
{
244+
name: "Test null body response",
245+
internalReq: &internalRequest{
246+
endpoint: "/test-null-body",
247+
method: http.MethodGet,
248+
withResponse: make([]byte, 0),
249+
contentType: "application/json",
250+
acceptedStatusCodes: []int{http.StatusOK},
251+
},
252+
expectedResp: nil,
253+
wantErr: false,
254+
},
239255
{
240256
name: "400 Bad Request",
241257
internalReq: &internalRequest{

index.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,28 @@ type IndexManager interface {
580580
// https://www.meilisearch.com/docs/reference/api/settings#reset-proximity-precision-settings
581581
ResetProximityPrecisionWithContext(ctx context.Context) (*TaskInfo, error)
582582

583+
// GetLocalizedAttributes get the localized attributes settings of an index
584+
// https://www.meilisearch.com/docs/reference/api/settings#get-localized-attributes-settings
585+
GetLocalizedAttributes() ([]*LocalizedAttributes, error)
586+
587+
// GetLocalizedAttributesWithContext get the localized attributes settings of an index using the provided context for cancellation
588+
// https://www.meilisearch.com/docs/reference/api/settings#get-localized-attributes-settings
589+
GetLocalizedAttributesWithContext(ctx context.Context) ([]*LocalizedAttributes, error)
590+
591+
// UpdateLocalizedAttributes update the localized attributes settings of an index
592+
// https://www.meilisearch.com/docs/reference/api/settings#update-localized-attribute-settings
593+
UpdateLocalizedAttributes(request []*LocalizedAttributes) (*TaskInfo, error)
594+
595+
// UpdateLocalizedAttributesWithContext update the localized attributes settings of an index using the provided context for cancellation
596+
// https://www.meilisearch.com/docs/reference/api/settings#update-localized-attribute-settings
597+
UpdateLocalizedAttributesWithContext(ctx context.Context, request []*LocalizedAttributes) (*TaskInfo, error)
598+
599+
// ResetLocalizedAttributes reset the localized attributes settings
600+
ResetLocalizedAttributes() (*TaskInfo, error)
601+
602+
// ResetLocalizedAttributesWithContext reset the localized attributes settings using the provided context for cancellation
603+
ResetLocalizedAttributesWithContext(ctx context.Context) (*TaskInfo, error)
604+
583605
// WaitForTask waits for a task to complete by its UID with the given interval.
584606
WaitForTask(taskUID int64, interval time.Duration) (*Task, error)
585607

index_search_test.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ func TestIndex_Search(t *testing.T) {
381381
"book_id": float64(123), "title": "Pride and Prejudice",
382382
},
383383
},
384-
EstimatedTotalHits: 21,
384+
EstimatedTotalHits: 22,
385385
Offset: 0,
386386
Limit: 1,
387387
},
@@ -735,6 +735,28 @@ func TestIndex_Search(t *testing.T) {
735735
want: nil,
736736
wantErr: true,
737737
},
738+
{
739+
name: "TestIndexSearchWithLocate",
740+
args: args{
741+
UID: "indexUID",
742+
client: sv,
743+
query: "王子",
744+
request: &SearchRequest{
745+
Locates: []string{"jpn"},
746+
},
747+
},
748+
want: &SearchResponse{
749+
Hits: []interface{}{
750+
map[string]interface{}{
751+
"book_id": float64(1050), "title": "星の王子さま",
752+
},
753+
},
754+
EstimatedTotalHits: 1,
755+
Offset: 0,
756+
Limit: 20,
757+
},
758+
wantErr: false,
759+
},
738760
}
739761
for _, tt := range tests {
740762
t.Run(tt.name, func(t *testing.T) {
@@ -1463,7 +1485,7 @@ func TestIndex_SearchWithSort(t *testing.T) {
14631485
"book_id": float64(7), "title": "Don Quixote",
14641486
},
14651487
},
1466-
EstimatedTotalHits: 21,
1488+
EstimatedTotalHits: 22,
14671489
Offset: 0,
14681490
Limit: 4,
14691491
},

index_settings.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,3 +1102,65 @@ func (i *index) ResetProximityPrecisionWithContext(ctx context.Context) (*TaskIn
11021102
}
11031103
return resp, nil
11041104
}
1105+
1106+
func (i *index) GetLocalizedAttributes() ([]*LocalizedAttributes, error) {
1107+
return i.GetLocalizedAttributesWithContext(context.Background())
1108+
}
1109+
1110+
func (i *index) GetLocalizedAttributesWithContext(ctx context.Context) ([]*LocalizedAttributes, error) {
1111+
resp := make([]*LocalizedAttributes, 0)
1112+
req := &internalRequest{
1113+
endpoint: "/indexes/" + i.uid + "/settings/localized-attributes",
1114+
method: http.MethodGet,
1115+
withRequest: nil,
1116+
withResponse: &resp,
1117+
acceptedStatusCodes: []int{http.StatusOK},
1118+
functionName: "GetLocalizedAttributes",
1119+
}
1120+
if err := i.client.executeRequest(ctx, req); err != nil {
1121+
return nil, err
1122+
}
1123+
return resp, nil
1124+
}
1125+
1126+
func (i *index) UpdateLocalizedAttributes(request []*LocalizedAttributes) (*TaskInfo, error) {
1127+
return i.UpdateLocalizedAttributesWithContext(context.Background(), request)
1128+
}
1129+
1130+
func (i *index) UpdateLocalizedAttributesWithContext(ctx context.Context, request []*LocalizedAttributes) (*TaskInfo, error) {
1131+
1132+
resp := new(TaskInfo)
1133+
req := &internalRequest{
1134+
endpoint: "/indexes/" + i.uid + "/settings/localized-attributes",
1135+
method: http.MethodPut,
1136+
withRequest: request,
1137+
withResponse: resp,
1138+
contentType: contentTypeJSON,
1139+
acceptedStatusCodes: []int{http.StatusAccepted},
1140+
functionName: "UpdateLocalizedAttributes",
1141+
}
1142+
if err := i.client.executeRequest(ctx, req); err != nil {
1143+
return nil, err
1144+
}
1145+
return resp, nil
1146+
}
1147+
1148+
func (i *index) ResetLocalizedAttributes() (*TaskInfo, error) {
1149+
return i.ResetLocalizedAttributesWithContext(context.Background())
1150+
}
1151+
1152+
func (i *index) ResetLocalizedAttributesWithContext(ctx context.Context) (*TaskInfo, error) {
1153+
resp := new(TaskInfo)
1154+
req := &internalRequest{
1155+
endpoint: "/indexes/" + i.uid + "/settings/localized-attributes",
1156+
method: http.MethodDelete,
1157+
withRequest: nil,
1158+
withResponse: resp,
1159+
acceptedStatusCodes: []int{http.StatusAccepted},
1160+
functionName: "ResetLocalizedAttributes",
1161+
}
1162+
if err := i.client.executeRequest(ctx, req); err != nil {
1163+
return nil, err
1164+
}
1165+
return resp, nil
1166+
}

index_settings_test.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ func TestIndex_GetSettings(t *testing.T) {
259259
SeparatorTokens: make([]string, 0),
260260
NonSeparatorTokens: make([]string, 0),
261261
Dictionary: make([]string, 0),
262+
LocalizedAttributes: nil,
262263
},
263264
},
264265
{
@@ -284,6 +285,7 @@ func TestIndex_GetSettings(t *testing.T) {
284285
SeparatorTokens: make([]string, 0),
285286
NonSeparatorTokens: make([]string, 0),
286287
Dictionary: make([]string, 0),
288+
LocalizedAttributes: nil,
287289
},
288290
},
289291
}
@@ -893,6 +895,7 @@ func TestIndex_ResetSettings(t *testing.T) {
893895
SeparatorTokens: make([]string, 0),
894896
NonSeparatorTokens: make([]string, 0),
895897
Dictionary: make([]string, 0),
898+
LocalizedAttributes: nil,
896899
},
897900
},
898901
{
@@ -920,6 +923,7 @@ func TestIndex_ResetSettings(t *testing.T) {
920923
SeparatorTokens: make([]string, 0),
921924
NonSeparatorTokens: make([]string, 0),
922925
Dictionary: make([]string, 0),
926+
LocalizedAttributes: nil,
923927
},
924928
},
925929
}
@@ -1698,6 +1702,12 @@ func TestIndex_UpdateSettings(t *testing.T) {
16981702
SeparatorTokens: make([]string, 0),
16991703
NonSeparatorTokens: make([]string, 0),
17001704
Dictionary: make([]string, 0),
1705+
LocalizedAttributes: []*LocalizedAttributes{
1706+
{
1707+
Locales: []string{"jpn", "eng"},
1708+
AttributePatterns: []string{"*_ja"},
1709+
},
1710+
},
17011711
},
17021712
},
17031713
wantTask: &TaskInfo{
@@ -1720,6 +1730,12 @@ func TestIndex_UpdateSettings(t *testing.T) {
17201730
SeparatorTokens: make([]string, 0),
17211731
NonSeparatorTokens: make([]string, 0),
17221732
Dictionary: make([]string, 0),
1733+
LocalizedAttributes: []*LocalizedAttributes{
1734+
{
1735+
Locales: []string{"jpn", "eng"},
1736+
AttributePatterns: []string{"*_ja"},
1737+
},
1738+
},
17231739
},
17241740
},
17251741
{
@@ -3687,3 +3703,56 @@ func Test_ProximityPrecision(t *testing.T) {
36873703
require.NoError(t, err)
36883704
require.Equal(t, ByWord, got)
36893705
}
3706+
3707+
func Test_LocalizedAttributes(t *testing.T) {
3708+
c := setup(t, "")
3709+
t.Cleanup(cleanup(c))
3710+
3711+
indexID := "newIndexUID"
3712+
i := c.Index(indexID)
3713+
taskInfo, err := c.CreateIndex(&IndexConfig{Uid: indexID})
3714+
require.NoError(t, err)
3715+
testWaitForTask(t, i, taskInfo)
3716+
3717+
defer t.Cleanup(cleanup(c))
3718+
3719+
t.Run("Test valid locate", func(t *testing.T) {
3720+
got, err := i.GetLocalizedAttributes()
3721+
require.NoError(t, err)
3722+
require.Len(t, got, 0)
3723+
3724+
localized := &LocalizedAttributes{
3725+
Locales: []string{"jpn", "eng"},
3726+
AttributePatterns: []string{"*_ja"},
3727+
}
3728+
3729+
task, err := i.UpdateLocalizedAttributes([]*LocalizedAttributes{localized})
3730+
require.NoError(t, err)
3731+
testWaitForTask(t, i, task)
3732+
3733+
got, err = i.GetLocalizedAttributes()
3734+
require.NoError(t, err)
3735+
require.NotNil(t, got)
3736+
3737+
require.Equal(t, localized.Locales, got[0].Locales)
3738+
require.Equal(t, localized.AttributePatterns, got[0].AttributePatterns)
3739+
3740+
task, err = i.ResetLocalizedAttributes()
3741+
require.NoError(t, err)
3742+
testWaitForTask(t, i, task)
3743+
3744+
got, err = i.GetLocalizedAttributes()
3745+
require.NoError(t, err)
3746+
require.Len(t, got, 0)
3747+
})
3748+
3749+
t.Run("Test invalid locate", func(t *testing.T) {
3750+
invalidLocalized := &LocalizedAttributes{
3751+
Locales: []string{"foo"},
3752+
AttributePatterns: []string{"*_ja"},
3753+
}
3754+
3755+
_, err := i.UpdateLocalizedAttributes([]*LocalizedAttributes{invalidLocalized})
3756+
require.Error(t, err)
3757+
})
3758+
}

main_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ func setUpIndexForFaceting(client ServiceManager) {
235235
{BookID: 921, Title: "The Brothers Karamazov", Tag: "Novel", Year: 1879},
236236
{BookID: 1032, Title: "Crime and Punishment", Tag: "Crime fiction", Year: 1866},
237237
{BookID: 1039, Title: "The Girl in the white shirt", Tag: "white shirt", Year: 1999},
238+
{BookID: 1050, Title: "星の王子さま", Tag: "物語", Year: 1943},
238239
}
239240
task, err := idx.AddDocuments(booksTest)
240241
if err != nil {

types.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ const (
2929
HuffmanOnlyCompression EncodingCompressionLevel = -2
3030
ConstantCompression EncodingCompressionLevel = -2
3131
StatelessCompression EncodingCompressionLevel = -3
32+
33+
nullBody = "null"
3234
)
3335

3436
func (c ContentEncoding) String() string { return string(c) }
@@ -80,12 +82,18 @@ type Settings struct {
8082
Synonyms map[string][]string `json:"synonyms,omitempty"`
8183
FilterableAttributes []string `json:"filterableAttributes,omitempty"`
8284
SortableAttributes []string `json:"sortableAttributes,omitempty"`
85+
LocalizedAttributes []*LocalizedAttributes `json:"localizedAttributes,omitempty"`
8386
TypoTolerance *TypoTolerance `json:"typoTolerance,omitempty"`
8487
Pagination *Pagination `json:"pagination,omitempty"`
8588
Faceting *Faceting `json:"faceting,omitempty"`
8689
Embedders map[string]Embedder `json:"embedders,omitempty"`
8790
}
8891

92+
type LocalizedAttributes struct {
93+
Locales []string `json:"locales,omitempty"`
94+
AttributePatterns []string `json:"attributePatterns,omitempty"`
95+
}
96+
8997
// TypoTolerance is the type that represents the typo tolerance setting in meilisearch
9098
type TypoTolerance struct {
9199
Enabled bool `json:"enabled"`
@@ -429,6 +437,7 @@ type SearchRequest struct {
429437
RetrieveVectors bool `json:"retrieveVectors,omitempty"`
430438
RankingScoreThreshold float64 `json:"rankingScoreThreshold,omitempty"`
431439
FederationOptions *SearchFederationOptions `json:"federationOptions,omitempty"`
440+
Locates []string `json:"locales,omitempty"`
432441
}
433442

434443
type SearchFederationOptions struct {

0 commit comments

Comments
 (0)