Skip to content

Commit

Permalink
Merge #580
Browse files Browse the repository at this point in the history
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 <ja7ad@live.com>
  • Loading branch information
meili-bors[bot] and Ja7ad authored Oct 2, 2024
2 parents 1cd56a5 + 63cf6b8 commit 92b1ab7
Show file tree
Hide file tree
Showing 10 changed files with 928 additions and 480 deletions.
12 changes: 12 additions & 0 deletions .code-samples.meilisearch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -939,3 +939,15 @@ update_proximity_precision_settings_1: |-
client.Index("books").UpdateProximityPrecision(ByAttribute)
reset_proximity_precision_settings_1: |-
client.Index("books").ResetProximityPrecision()
search_parameter_reference_locales_1: |-
client.index("INDEX_NAME").Search("進撃の巨人", &meilisearch.SearchRequest{
Locates: []string{"jpn"}
})
get_localized_attribute_settings_1: |-
client.index("INDEX_NAME").GetLocalizedAttributes()
update_localized_attribute_settings_1: |-
client.index("INDEX_NAME").UpdateLocalizedAttributes([]*LocalizedAttributes{
{ AttributePatterns: ["*_ja"], Locales: ["jpn"] },
})
reset_localized_attribute_settings_1: |-
client.index("INDEX_NAME").ResetLocalizedAttributes()
5 changes: 5 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,11 @@ func (c *client) handleResponse(req *internalRequest, body []byte, internalError
} else {
internalError.ResponseToString = string(body)

if internalError.ResponseToString == nullBody {
req.withResponse = nil
return nil
}

var err error
if resp, ok := req.withResponse.(json.Unmarshaler); ok {
err = resp.UnmarshalJSON(body)
Expand Down
16 changes: 16 additions & 0 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ func TestExecuteRequest(t *testing.T) {
msg := []byte(`{"message":"post successful"}`)
_, _ = w.Write(msg)

} else if r.Method == http.MethodGet && r.URL.Path == "/test-null-body" {
w.WriteHeader(http.StatusOK)
msg := []byte(`null`)
_, _ = w.Write(msg)
} else if r.Method == http.MethodPost && r.URL.Path == "/test-post-encoding" {
w.WriteHeader(http.StatusCreated)
msg := []byte(`{"message":"post successful"}`)
Expand Down Expand Up @@ -236,6 +240,18 @@ func TestExecuteRequest(t *testing.T) {
expectedResp: nil,
wantErr: false,
},
{
name: "Test null body response",
internalReq: &internalRequest{
endpoint: "/test-null-body",
method: http.MethodGet,
withResponse: make([]byte, 0),
contentType: "application/json",
acceptedStatusCodes: []int{http.StatusOK},
},
expectedResp: nil,
wantErr: false,
},
{
name: "400 Bad Request",
internalReq: &internalRequest{
Expand Down
22 changes: 22 additions & 0 deletions index.go
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,28 @@ type IndexManager interface {
// https://www.meilisearch.com/docs/reference/api/settings#reset-proximity-precision-settings
ResetProximityPrecisionWithContext(ctx context.Context) (*TaskInfo, error)

// GetLocalizedAttributes get the localized attributes settings of an index
// https://www.meilisearch.com/docs/reference/api/settings#get-localized-attributes-settings
GetLocalizedAttributes() ([]*LocalizedAttributes, error)

// GetLocalizedAttributesWithContext get the localized attributes settings of an index using the provided context for cancellation
// https://www.meilisearch.com/docs/reference/api/settings#get-localized-attributes-settings
GetLocalizedAttributesWithContext(ctx context.Context) ([]*LocalizedAttributes, error)

// UpdateLocalizedAttributes update the localized attributes settings of an index
// https://www.meilisearch.com/docs/reference/api/settings#update-localized-attribute-settings
UpdateLocalizedAttributes(request []*LocalizedAttributes) (*TaskInfo, error)

// UpdateLocalizedAttributesWithContext update the localized attributes settings of an index using the provided context for cancellation
// https://www.meilisearch.com/docs/reference/api/settings#update-localized-attribute-settings
UpdateLocalizedAttributesWithContext(ctx context.Context, request []*LocalizedAttributes) (*TaskInfo, error)

// ResetLocalizedAttributes reset the localized attributes settings
ResetLocalizedAttributes() (*TaskInfo, error)

// ResetLocalizedAttributesWithContext reset the localized attributes settings using the provided context for cancellation
ResetLocalizedAttributesWithContext(ctx context.Context) (*TaskInfo, error)

// WaitForTask waits for a task to complete by its UID with the given interval.
WaitForTask(taskUID int64, interval time.Duration) (*Task, error)

Expand Down
26 changes: 24 additions & 2 deletions index_search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ func TestIndex_Search(t *testing.T) {
"book_id": float64(123), "title": "Pride and Prejudice",
},
},
EstimatedTotalHits: 21,
EstimatedTotalHits: 22,
Offset: 0,
Limit: 1,
},
Expand Down Expand Up @@ -735,6 +735,28 @@ func TestIndex_Search(t *testing.T) {
want: nil,
wantErr: true,
},
{
name: "TestIndexSearchWithLocate",
args: args{
UID: "indexUID",
client: sv,
query: "王子",
request: &SearchRequest{
Locates: []string{"jpn"},
},
},
want: &SearchResponse{
Hits: []interface{}{
map[string]interface{}{
"book_id": float64(1050), "title": "星の王子さま",
},
},
EstimatedTotalHits: 1,
Offset: 0,
Limit: 20,
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down Expand Up @@ -1463,7 +1485,7 @@ func TestIndex_SearchWithSort(t *testing.T) {
"book_id": float64(7), "title": "Don Quixote",
},
},
EstimatedTotalHits: 21,
EstimatedTotalHits: 22,
Offset: 0,
Limit: 4,
},
Expand Down
62 changes: 62 additions & 0 deletions index_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -1102,3 +1102,65 @@ func (i *index) ResetProximityPrecisionWithContext(ctx context.Context) (*TaskIn
}
return resp, nil
}

func (i *index) GetLocalizedAttributes() ([]*LocalizedAttributes, error) {
return i.GetLocalizedAttributesWithContext(context.Background())
}

func (i *index) GetLocalizedAttributesWithContext(ctx context.Context) ([]*LocalizedAttributes, error) {
resp := make([]*LocalizedAttributes, 0)
req := &internalRequest{
endpoint: "/indexes/" + i.uid + "/settings/localized-attributes",
method: http.MethodGet,
withRequest: nil,
withResponse: &resp,
acceptedStatusCodes: []int{http.StatusOK},
functionName: "GetLocalizedAttributes",
}
if err := i.client.executeRequest(ctx, req); err != nil {
return nil, err
}
return resp, nil
}

func (i *index) UpdateLocalizedAttributes(request []*LocalizedAttributes) (*TaskInfo, error) {
return i.UpdateLocalizedAttributesWithContext(context.Background(), request)
}

func (i *index) UpdateLocalizedAttributesWithContext(ctx context.Context, request []*LocalizedAttributes) (*TaskInfo, error) {

resp := new(TaskInfo)
req := &internalRequest{
endpoint: "/indexes/" + i.uid + "/settings/localized-attributes",
method: http.MethodPut,
withRequest: request,
withResponse: resp,
contentType: contentTypeJSON,
acceptedStatusCodes: []int{http.StatusAccepted},
functionName: "UpdateLocalizedAttributes",
}
if err := i.client.executeRequest(ctx, req); err != nil {
return nil, err
}
return resp, nil
}

func (i *index) ResetLocalizedAttributes() (*TaskInfo, error) {
return i.ResetLocalizedAttributesWithContext(context.Background())
}

func (i *index) ResetLocalizedAttributesWithContext(ctx context.Context) (*TaskInfo, error) {
resp := new(TaskInfo)
req := &internalRequest{
endpoint: "/indexes/" + i.uid + "/settings/localized-attributes",
method: http.MethodDelete,
withRequest: nil,
withResponse: resp,
acceptedStatusCodes: []int{http.StatusAccepted},
functionName: "ResetLocalizedAttributes",
}
if err := i.client.executeRequest(ctx, req); err != nil {
return nil, err
}
return resp, nil
}
69 changes: 69 additions & 0 deletions index_settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ func TestIndex_GetSettings(t *testing.T) {
SeparatorTokens: make([]string, 0),
NonSeparatorTokens: make([]string, 0),
Dictionary: make([]string, 0),
LocalizedAttributes: nil,
},
},
{
Expand All @@ -284,6 +285,7 @@ func TestIndex_GetSettings(t *testing.T) {
SeparatorTokens: make([]string, 0),
NonSeparatorTokens: make([]string, 0),
Dictionary: make([]string, 0),
LocalizedAttributes: nil,
},
},
}
Expand Down Expand Up @@ -893,6 +895,7 @@ func TestIndex_ResetSettings(t *testing.T) {
SeparatorTokens: make([]string, 0),
NonSeparatorTokens: make([]string, 0),
Dictionary: make([]string, 0),
LocalizedAttributes: nil,
},
},
{
Expand Down Expand Up @@ -920,6 +923,7 @@ func TestIndex_ResetSettings(t *testing.T) {
SeparatorTokens: make([]string, 0),
NonSeparatorTokens: make([]string, 0),
Dictionary: make([]string, 0),
LocalizedAttributes: nil,
},
},
}
Expand Down Expand Up @@ -1698,6 +1702,12 @@ func TestIndex_UpdateSettings(t *testing.T) {
SeparatorTokens: make([]string, 0),
NonSeparatorTokens: make([]string, 0),
Dictionary: make([]string, 0),
LocalizedAttributes: []*LocalizedAttributes{
{
Locales: []string{"jpn", "eng"},
AttributePatterns: []string{"*_ja"},
},
},
},
},
wantTask: &TaskInfo{
Expand All @@ -1720,6 +1730,12 @@ func TestIndex_UpdateSettings(t *testing.T) {
SeparatorTokens: make([]string, 0),
NonSeparatorTokens: make([]string, 0),
Dictionary: make([]string, 0),
LocalizedAttributes: []*LocalizedAttributes{
{
Locales: []string{"jpn", "eng"},
AttributePatterns: []string{"*_ja"},
},
},
},
},
{
Expand Down Expand Up @@ -3687,3 +3703,56 @@ func Test_ProximityPrecision(t *testing.T) {
require.NoError(t, err)
require.Equal(t, ByWord, got)
}

func Test_LocalizedAttributes(t *testing.T) {
c := setup(t, "")
t.Cleanup(cleanup(c))

indexID := "newIndexUID"
i := c.Index(indexID)
taskInfo, err := c.CreateIndex(&IndexConfig{Uid: indexID})
require.NoError(t, err)
testWaitForTask(t, i, taskInfo)

defer t.Cleanup(cleanup(c))

t.Run("Test valid locate", func(t *testing.T) {
got, err := i.GetLocalizedAttributes()
require.NoError(t, err)
require.Len(t, got, 0)

localized := &LocalizedAttributes{
Locales: []string{"jpn", "eng"},
AttributePatterns: []string{"*_ja"},
}

task, err := i.UpdateLocalizedAttributes([]*LocalizedAttributes{localized})
require.NoError(t, err)
testWaitForTask(t, i, task)

got, err = i.GetLocalizedAttributes()
require.NoError(t, err)
require.NotNil(t, got)

require.Equal(t, localized.Locales, got[0].Locales)
require.Equal(t, localized.AttributePatterns, got[0].AttributePatterns)

task, err = i.ResetLocalizedAttributes()
require.NoError(t, err)
testWaitForTask(t, i, task)

got, err = i.GetLocalizedAttributes()
require.NoError(t, err)
require.Len(t, got, 0)
})

t.Run("Test invalid locate", func(t *testing.T) {
invalidLocalized := &LocalizedAttributes{
Locales: []string{"foo"},
AttributePatterns: []string{"*_ja"},
}

_, err := i.UpdateLocalizedAttributes([]*LocalizedAttributes{invalidLocalized})
require.Error(t, err)
})
}
1 change: 1 addition & 0 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ func setUpIndexForFaceting(client ServiceManager) {
{BookID: 921, Title: "The Brothers Karamazov", Tag: "Novel", Year: 1879},
{BookID: 1032, Title: "Crime and Punishment", Tag: "Crime fiction", Year: 1866},
{BookID: 1039, Title: "The Girl in the white shirt", Tag: "white shirt", Year: 1999},
{BookID: 1050, Title: "星の王子さま", Tag: "物語", Year: 1943},
}
task, err := idx.AddDocuments(booksTest)
if err != nil {
Expand Down
9 changes: 9 additions & 0 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ const (
HuffmanOnlyCompression EncodingCompressionLevel = -2
ConstantCompression EncodingCompressionLevel = -2
StatelessCompression EncodingCompressionLevel = -3

nullBody = "null"
)

func (c ContentEncoding) String() string { return string(c) }
Expand Down Expand Up @@ -80,12 +82,18 @@ type Settings struct {
Synonyms map[string][]string `json:"synonyms,omitempty"`
FilterableAttributes []string `json:"filterableAttributes,omitempty"`
SortableAttributes []string `json:"sortableAttributes,omitempty"`
LocalizedAttributes []*LocalizedAttributes `json:"localizedAttributes,omitempty"`
TypoTolerance *TypoTolerance `json:"typoTolerance,omitempty"`
Pagination *Pagination `json:"pagination,omitempty"`
Faceting *Faceting `json:"faceting,omitempty"`
Embedders map[string]Embedder `json:"embedders,omitempty"`
}

type LocalizedAttributes struct {
Locales []string `json:"locales,omitempty"`
AttributePatterns []string `json:"attributePatterns,omitempty"`
}

// TypoTolerance is the type that represents the typo tolerance setting in meilisearch
type TypoTolerance struct {
Enabled bool `json:"enabled"`
Expand Down Expand Up @@ -429,6 +437,7 @@ type SearchRequest struct {
RetrieveVectors bool `json:"retrieveVectors,omitempty"`
RankingScoreThreshold float64 `json:"rankingScoreThreshold,omitempty"`
FederationOptions *SearchFederationOptions `json:"federationOptions,omitempty"`
Locates []string `json:"locales,omitempty"`
}

type SearchFederationOptions struct {
Expand Down
Loading

0 comments on commit 92b1ab7

Please sign in to comment.