Skip to content

Commit 1f4a74c

Browse files
committed
feat: add localized atteribute for search and index settings
1 parent 2a54493 commit 1f4a74c

9 files changed

+975
-468
lines changed

.code-samples.meilisearch.yaml

+10
Original file line numberDiff line numberDiff line change
@@ -935,3 +935,13 @@ update_proximity_precision_settings_1: |-
935935
client.Index("books").UpdateProximityPrecision(ByAttribute)
936936
reset_proximity_precision_settings_1: |-
937937
client.Index("books").ResetProximityPrecision()
938+
search_parameter_reference_locales_1: |-
939+
client.index('INDEX_NAME').search('進撃の巨人', { locales: ['jpn'] })
940+
get_localized_attribute_settings_1: |-
941+
client.index('INDEX_NAME').GetLocalizedAttributes()
942+
update_localized_attribute_settings_1: |-
943+
client.index('INDEX_NAME').UpdateLocalizedAttributes([
944+
{ attributePatterns: ['jpn'], locales: ['*_ja'] },
945+
])
946+
reset_localized_attribute_settings_1: |-
947+
client.index('INDEX_NAME').ResetLocalizedAttributes()

index.go

+22
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

+24-2
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+
Locate: []Locate{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

+62
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

+69
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: []Locate{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: []Locate{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: []Locate{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: []Locate{"foo"},
3752+
AttributePatterns: []string{"*_ja"},
3753+
}
3754+
3755+
_, err := i.UpdateLocalizedAttributes([]*LocalizedAttributes{invalidLocalized})
3756+
require.Error(t, err)
3757+
})
3758+
}

locate.go

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package meilisearch
2+
3+
// Locate is localized attributes for index in search
4+
//
5+
// https://www.meilisearch.com/docs/reference/api/settings#localized-attributes-object
6+
type Locate string
7+
8+
const (
9+
EPO Locate = "epo" // EPO is Esperanto
10+
ENG Locate = "eng" // ENG is English
11+
RUS Locate = "rus" // RUS is Russian
12+
CMN Locate = "cmn" // CMN is Mandarin Chinese
13+
SPA Locate = "spa" // SPA is Spanish
14+
POR Locate = "por" // POR is Portuguese
15+
ITA Locate = "ita" // ITA is Italian
16+
BEN Locate = "ben" // BEN is Bengali
17+
FRA Locate = "fra" // FRA is French
18+
DEU Locate = "deu" // DEU is German
19+
UKR Locate = "ukr" // UKR is Ukrainian
20+
KAT Locate = "kat" // KAT is Georgian
21+
ARA Locate = "ara" // ARA is Arabic
22+
HIN Locate = "hin" // HIN is Hindi
23+
JPN Locate = "jpn" // JPN is Japanese
24+
HEB Locate = "heb" // HEB is Hebrew
25+
YID Locate = "yid" // YID is Yiddish
26+
POL Locate = "pol" // POL is Polish
27+
AMH Locate = "amh" // AMH is Amharic
28+
JAV Locate = "jav" // JAV is Javanese
29+
KOR Locate = "kor" // KOR is Korean
30+
NOB Locate = "nob" // NOB is Norwegian Bokmål
31+
DAN Locate = "dan" // DAN is Danish
32+
SWE Locate = "swe" // SWE is Swedish
33+
FIN Locate = "fin" // FIN is Finnish
34+
TUR Locate = "tur" // TUR is Turkish
35+
NLD Locate = "nld" // NLD is Dutch
36+
HUN Locate = "hun" // HUN is Hungarian
37+
CES Locate = "ces" // CES is Czech
38+
ELL Locate = "ell" // ELL is Greek
39+
BUL Locate = "bul" // BUL is Bulgarian
40+
BEL Locate = "bel" // BEL is Belarusian
41+
MAR Locate = "mar" // MAR is Marathi
42+
KAN Locate = "kan" // KAN is Kannada
43+
RON Locate = "ron" // RON is Romanian
44+
SLV Locate = "slv" // SLV is Slovenian
45+
HRV Locate = "hrv" // HRV is Croatian
46+
SRP Locate = "srp" // SRP is Serbian
47+
MKD Locate = "mkd" // MKD is Macedonian
48+
LIT Locate = "lit" // LIT is Lithuanian
49+
LAV Locate = "lav" // LAV is Latvian
50+
EST Locate = "est" // EST is Estonian
51+
TAM Locate = "tam" // TAM is Tamil
52+
VIE Locate = "vie" // VIE is Vietnamese
53+
URD Locate = "urd" // URD is Urdu
54+
THA Locate = "tha" // THA is Thai
55+
GUJ Locate = "guj" // GUJ is Gujarati
56+
UZB Locate = "uzb" // UZB is Uzbek
57+
PAN Locate = "pan" // PAN is Punjabi
58+
AZE Locate = "aze" // AZE is Azerbaijani
59+
IND Locate = "ind" // IND is Indonesian
60+
TEL Locate = "tel" // TEL is Telugu
61+
PES Locate = "pes" // PES is Persian
62+
MAL Locate = "mal" // MAL is Malayalam
63+
ORI Locate = "ori" // ORI is Odia
64+
MYA Locate = "mya" // MYA is Burmese
65+
NEP Locate = "nep" // NEP is Nepali
66+
SIN Locate = "sin" // SIN is Sinhala
67+
KHM Locate = "khm" // KHM is Khmer
68+
TUK Locate = "tuk" // TUK is Turkmen
69+
AKA Locate = "aka" // AKA is Akan
70+
ZUL Locate = "zul" // ZUL is Zulu
71+
SNA Locate = "sna" // SNA is Shona
72+
AFR Locate = "afr" // AFR is Afrikaans
73+
LAT Locate = "lat" // LAT is Latin
74+
SLK Locate = "slk" // SLK is Slovak
75+
CAT Locate = "cat" // CAT is Catalan
76+
TGL Locate = "tgl" // TGL is Tagalog
77+
HYE Locate = "hye" // HYE is Armenian
78+
)
79+
80+
func (l Locate) String() string {
81+
return string(l)
82+
}

main_test.go

+1
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

+9
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 []Locate `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+
Locate []Locate `json:"locales,omitempty"`
432441
}
433442

434443
type SearchFederationOptions struct {

0 commit comments

Comments
 (0)