Skip to content

Commit 0165e9b

Browse files
Merge #656
656: update: filterable attributes opt-out r=ja7ad a=ElyarSadig # Pull Request ## Related issue Fixes #626 ## What does this PR do? - Add new filterable attributes settings type - Update UpdateFilterableAttributes to accept []interface{} to allow for the new settings syntax - Update GetFilterableAttributes to support the new settings syntax ## 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! <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for advanced filterable attribute configuration using new attribute rule structures, enabling more flexible filtering options. * **Bug Fixes** * Improved handling of filterable attributes to accept both simple strings and complex objects. * **Tests** * Updated and expanded test coverage to validate new filterable attribute formats and scenarios. * **API Changes** * Modified method signatures and data structures to support heterogeneous filterable attribute types. Existing integrations using filterable attributes may require updates. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: elyar <[email protected]>
2 parents 8bdd47f + cfb56ea commit 0165e9b

File tree

9 files changed

+220
-42
lines changed

9 files changed

+220
-42
lines changed

.code-samples.meilisearch.yaml

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -302,9 +302,29 @@ reset_distinct_attribute_1: |-
302302
get_filterable_attributes_1: |-
303303
client.Index("movies").GetFilterableAttributes()
304304
update_filterable_attributes_1: |-
305-
filterableAttributes := []string{
305+
filterableAttributes := []interface{}{
306306
"genres",
307307
"director",
308+
AttributeRule{
309+
AttributePatterns: []string{"tag"}
310+
Features: AttributeFeatures{
311+
FacetSearch: false,
312+
Filter: FilterFeatures{
313+
Equality: true,
314+
Comparison: false,
315+
}
316+
}
317+
},
318+
map[string]interface{}{
319+
"attributePatterns": []interface{}{"year"}
320+
"features": map[string]interface{}{
321+
"facetSearch": false,
322+
"filter": map[string]interface{}{
323+
"equality": true,
324+
"comparison": true,
325+
}
326+
}
327+
}
308328
}
309329
client.Index("movies").UpdateFilterableAttributes(&filterableAttributes)
310330
reset_filterable_attributes_1: |-
@@ -676,7 +696,7 @@ getting_started_pagination: |-
676696
MaxTotalHits: 500,
677697
})
678698
filtering_update_settings_1: |-
679-
resp, err := client.Index("movies").UpdateFilterableAttributes(&[]string{
699+
resp, err := client.Index("movies").UpdateFilterableAttributes(&[]interface{}{
680700
"director",
681701
"genres",
682702
})
@@ -688,7 +708,7 @@ faceted_search_walkthrough_filter_1: |-
688708
},
689709
})
690710
faceted_search_update_settings_1: |-
691-
filterableAttributes := []string{
711+
filterableAttributes := []interface{}{
692712
"genres",
693713
"rating",
694714
"language",
@@ -747,7 +767,7 @@ search_parameter_guide_sort_1: |-
747767
},
748768
})
749769
geosearch_guide_filter_settings_1: |-
750-
filterableAttributes := []string{
770+
filterableAttributes := []interface{}{
751771
"_geo",
752772
}
753773
client.Index("restaurants").UpdateFilterableAttributes(&filterableAttributes)
@@ -858,7 +878,7 @@ date_guide_index_1: |-
858878
859879
client.Index("games").AddDocuments(games, nil)
860880
date_guide_filterable_attributes_1: |-
861-
filterableAttributes := []string{"release_timestamp"}
881+
filterableAttributes := []interface{}{"release_timestamp"}
862882
client.Index("games").UpdateFilterableAttributes(&filterableAttributes)
863883
date_guide_filter_1: |-
864884
client.Index("games").Search("", &meilisearch.SearchRequest{
@@ -882,7 +902,7 @@ distinct_attribute_guide_distinct_parameter_1: |-
882902
Distinct: "sku",
883903
})
884904
distinct_attribute_guide_filterable_1: |-
885-
filterableAttributes := []string{
905+
filterableAttributes := []interface{}{
886906
"product_id",
887907
"sku",
888908
"url",

index_document_test.go

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ package meilisearch
33
import (
44
"bytes"
55
"crypto/tls"
6-
"github.com/stretchr/testify/require"
76
"testing"
7+
8+
"github.com/stretchr/testify/require"
89
)
910

1011
func Test_GetDocumentsByIDS(t *testing.T) {
@@ -1377,7 +1378,7 @@ func TestIndex_DeleteDocumentsByFilter(t *testing.T) {
13771378
UID string
13781379
client ServiceManager
13791380
filterToDelete interface{}
1380-
filterToApply []string
1381+
filterToApply []interface{}
13811382
documentsPtr []docTestBooks
13821383
}
13831384
tests := []struct {
@@ -1390,7 +1391,7 @@ func TestIndex_DeleteDocumentsByFilter(t *testing.T) {
13901391
args: args{
13911392
UID: "1",
13921393
client: sv,
1393-
filterToApply: []string{"book_id"},
1394+
filterToApply: []interface{}{"book_id"},
13941395
filterToDelete: "book_id = 123",
13951396
documentsPtr: []docTestBooks{
13961397
{BookID: 123, Title: "Pride and Prejudice", Tag: "Romance", Year: 1813},
@@ -1407,7 +1408,7 @@ func TestIndex_DeleteDocumentsByFilter(t *testing.T) {
14071408
args: args{
14081409
UID: "1",
14091410
client: customSv,
1410-
filterToApply: []string{"tag"},
1411+
filterToApply: []interface{}{"tag"},
14111412
filterToDelete: []string{"tag = 'Epic fantasy'"},
14121413
documentsPtr: []docTestBooks{
14131414
{BookID: 1344, Title: "The Hobbit", Tag: "Epic fantasy", Year: 1937},
@@ -1426,7 +1427,7 @@ func TestIndex_DeleteDocumentsByFilter(t *testing.T) {
14261427
args: args{
14271428
UID: "1",
14281429
client: customSv,
1429-
filterToApply: []string{"tag", "year"},
1430+
filterToApply: []interface{}{"tag", "year"},
14301431
filterToDelete: []string{"tag = 'Epic fantasy'", "year > 1936"},
14311432
documentsPtr: []docTestBooks{
14321433
{BookID: 1344, Title: "The Hobbit", Tag: "Epic fantasy", Year: 1937},
@@ -1445,7 +1446,7 @@ func TestIndex_DeleteDocumentsByFilter(t *testing.T) {
14451446
args: args{
14461447
UID: "1",
14471448
client: customSv,
1448-
filterToApply: []string{"book_id", "tag"},
1449+
filterToApply: []interface{}{"book_id", "tag"},
14491450
filterToDelete: []interface{}{[]string{"tag = 'Epic fantasy'", "book_id = 123"}},
14501451
documentsPtr: []docTestBooks{
14511452
{BookID: 123, Title: "Pride and Prejudice", Tag: "Romance", Year: 1813},
@@ -1460,6 +1461,74 @@ func TestIndex_DeleteDocumentsByFilter(t *testing.T) {
14601461
Type: "documentDeletion",
14611462
},
14621463
},
1464+
{
1465+
name: "TestIndexDeleteWithAttributeRuleForTagAndYear",
1466+
args: args{
1467+
UID: "1",
1468+
client: customSv,
1469+
filterToApply: []interface{}{
1470+
AttributeRule{
1471+
AttributePatterns: []string{"tag"},
1472+
Features: AttributeFeatures{
1473+
FacetSearch: false,
1474+
Filter: FilterFeatures{
1475+
Equality: true,
1476+
Comparison: false,
1477+
},
1478+
},
1479+
},
1480+
AttributeRule{
1481+
AttributePatterns: []string{"year"},
1482+
Features: AttributeFeatures{
1483+
FacetSearch: false,
1484+
Filter: FilterFeatures{
1485+
Equality: true,
1486+
Comparison: true,
1487+
},
1488+
},
1489+
},
1490+
},
1491+
filterToDelete: []string{"tag = 'Fantasy'", "year > 1900"},
1492+
documentsPtr: []docTestBooks{
1493+
{BookID: 1, Title: "Fantasy Realms", Tag: "Fantasy", Year: 1950},
1494+
{BookID: 1344, Title: "The Hobbit", Tag: "Fantasy", Year: 1937},
1495+
},
1496+
},
1497+
wantResp: &TaskInfo{
1498+
TaskUID: 1,
1499+
Status: "enqueued",
1500+
Type: "documentDeletion",
1501+
},
1502+
},
1503+
{
1504+
name: "TestIndexDeleteWithMixedFilterableAttributes",
1505+
args: args{
1506+
UID: "1",
1507+
client: customSv,
1508+
filterToApply: []interface{}{
1509+
"title",
1510+
AttributeRule{
1511+
AttributePatterns: []string{"year"},
1512+
Features: AttributeFeatures{
1513+
FacetSearch: false,
1514+
Filter: FilterFeatures{
1515+
Equality: true,
1516+
Comparison: true,
1517+
},
1518+
},
1519+
},
1520+
},
1521+
filterToDelete: []string{"title = 'The Hobbit'", "year > 1930"},
1522+
documentsPtr: []docTestBooks{
1523+
{BookID: 1344, Title: "The Hobbit", Tag: "Fantasy", Year: 1937},
1524+
},
1525+
},
1526+
wantResp: &TaskInfo{
1527+
TaskUID: 1,
1528+
Status: "enqueued",
1529+
Type: "documentDeletion",
1530+
},
1531+
},
14631532
}
14641533
for _, tt := range tests {
14651534
t.Run(tt.name, func(t *testing.T) {

index_interface.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,10 @@ type SettingsManager interface {
312312
ResetSynonymsWithContext(ctx context.Context) (*TaskInfo, error)
313313

314314
// UpdateFilterableAttributes updates the filterable attributes of the index.
315-
UpdateFilterableAttributes(request *[]string) (*TaskInfo, error)
315+
UpdateFilterableAttributes(request *[]interface{}) (*TaskInfo, error)
316316

317317
// UpdateFilterableAttributesWithContext updates the filterable attributes of the index using the provided context for cancellation.
318-
UpdateFilterableAttributesWithContext(ctx context.Context, request *[]string) (*TaskInfo, error)
318+
UpdateFilterableAttributesWithContext(ctx context.Context, request *[]interface{}) (*TaskInfo, error)
319319

320320
// ResetFilterableAttributes resets the filterable attributes of the index to default values.
321321
ResetFilterableAttributes() (*TaskInfo, error)
@@ -542,10 +542,10 @@ type SettingsReader interface {
542542
GetSynonymsWithContext(ctx context.Context) (*map[string][]string, error)
543543

544544
// GetFilterableAttributes retrieves the filterable attributes of the index.
545-
GetFilterableAttributes() (*[]string, error)
545+
GetFilterableAttributes() (*[]interface{}, error)
546546

547547
// GetFilterableAttributesWithContext retrieves the filterable attributes of the index using the provided context for cancellation.
548-
GetFilterableAttributesWithContext(ctx context.Context) (*[]string, error)
548+
GetFilterableAttributesWithContext(ctx context.Context) (*[]interface{}, error)
549549

550550
// GetSortableAttributes retrieves the sortable attributes of the index.
551551
GetSortableAttributes() (*[]string, error)

index_search_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ func TestIndex_SearchWithContentEncoding(t *testing.T) {
128128
require.NoError(t, err, "error unmarshalling raw got SearchResponse")
129129
require.Equal(t, len(tt.Response.Hits), len(resp.Hits))
130130

131-
filterableAttrs := []string{"tag"}
131+
filterableAttrs := []interface{}{"tag"}
132132
task, err := i.UpdateFilterableAttributes(&filterableAttrs)
133133
require.NoError(t, err)
134134
testWaitForTask(t, i, task)
@@ -339,7 +339,7 @@ func TestIndex_SearchFacets(t *testing.T) {
339339
client ServiceManager
340340
query string
341341
request *SearchRequest
342-
filterableAttributes []string
342+
filterableAttributes []interface{}
343343
}
344344
tests := []struct {
345345
name string
@@ -367,7 +367,7 @@ func TestIndex_SearchFacets(t *testing.T) {
367367
request: &SearchRequest{
368368
Facets: []string{"*"},
369369
},
370-
filterableAttributes: []string{"tag"},
370+
filterableAttributes: []interface{}{"tag"},
371371
},
372372
want: &SearchResponse{
373373
Hits: Hits{
@@ -395,7 +395,7 @@ func TestIndex_SearchFacets(t *testing.T) {
395395
request: &SearchRequest{
396396
Facets: []string{"*"},
397397
},
398-
filterableAttributes: []string{"tag"},
398+
filterableAttributes: []interface{}{"tag"},
399399
},
400400
want: &SearchResponse{
401401
Hits: Hits{
@@ -423,7 +423,7 @@ func TestIndex_SearchFacets(t *testing.T) {
423423
request: &SearchRequest{
424424
Facets: []string{"book_id"},
425425
},
426-
filterableAttributes: []string{"book_id"},
426+
filterableAttributes: []interface{}{"book_id"},
427427
},
428428
want: &SearchResponse{
429429
Hits: Hits{
@@ -499,7 +499,7 @@ func TestIndex_SearchWithFilters(t *testing.T) {
499499
PrimaryKey string
500500
client ServiceManager
501501
query string
502-
filterableAttributes []string
502+
filterableAttributes []interface{}
503503
request *SearchRequest
504504
}
505505
tests := []struct {
@@ -514,7 +514,7 @@ func TestIndex_SearchWithFilters(t *testing.T) {
514514
UID: "indexUID",
515515
client: sv,
516516
query: "and",
517-
filterableAttributes: []string{"tag"},
517+
filterableAttributes: []interface{}{"tag"},
518518
request: &SearchRequest{
519519
Filter: "tag = romance",
520520
},
@@ -535,7 +535,7 @@ func TestIndex_SearchWithFilters(t *testing.T) {
535535
UID: "indexUID",
536536
client: sv,
537537
query: "and",
538-
filterableAttributes: []string{"year"},
538+
filterableAttributes: []interface{}{"year"},
539539
request: &SearchRequest{
540540
Filter: "year = 2005",
541541
},
@@ -1101,7 +1101,7 @@ func TestIndex_FacetSearch(t *testing.T) {
11011101
PrimaryKey string
11021102
client ServiceManager
11031103
request *FacetSearchRequest
1104-
filterableAttributes []string
1104+
filterableAttributes []interface{}
11051105
}
11061106

11071107
tests := []struct {
@@ -1119,7 +1119,7 @@ func TestIndex_FacetSearch(t *testing.T) {
11191119
FacetName: "tag",
11201120
FacetQuery: "Novel",
11211121
},
1122-
filterableAttributes: []string{"tag"},
1122+
filterableAttributes: []interface{}{"tag"},
11231123
},
11241124
want: &FacetSearchResponse{
11251125
FacetHits: Hits{
@@ -1160,7 +1160,7 @@ func TestIndex_FacetSearch(t *testing.T) {
11601160
Q: "query",
11611161
FacetName: "tag",
11621162
},
1163-
filterableAttributes: []string{"tag"},
1163+
filterableAttributes: []interface{}{"tag"},
11641164
},
11651165
want: &FacetSearchResponse{
11661166
FacetHits: Hits{},

index_settings.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -432,12 +432,12 @@ func (i *index) ResetSynonymsWithContext(ctx context.Context) (*TaskInfo, error)
432432
return resp, nil
433433
}
434434

435-
func (i *index) GetFilterableAttributes() (*[]string, error) {
435+
func (i *index) GetFilterableAttributes() (*[]interface{}, error) {
436436
return i.GetFilterableAttributesWithContext(context.Background())
437437
}
438438

439-
func (i *index) GetFilterableAttributesWithContext(ctx context.Context) (*[]string, error) {
440-
resp := &[]string{}
439+
func (i *index) GetFilterableAttributesWithContext(ctx context.Context) (*[]interface{}, error) {
440+
resp := &[]interface{}{}
441441
req := &internalRequest{
442442
endpoint: "/indexes/" + i.uid + "/settings/filterable-attributes",
443443
method: http.MethodGet,
@@ -452,11 +452,11 @@ func (i *index) GetFilterableAttributesWithContext(ctx context.Context) (*[]stri
452452
return resp, nil
453453
}
454454

455-
func (i *index) UpdateFilterableAttributes(request *[]string) (*TaskInfo, error) {
455+
func (i *index) UpdateFilterableAttributes(request *[]interface{}) (*TaskInfo, error) {
456456
return i.UpdateFilterableAttributesWithContext(context.Background(), request)
457457
}
458458

459-
func (i *index) UpdateFilterableAttributesWithContext(ctx context.Context, request *[]string) (*TaskInfo, error) {
459+
func (i *index) UpdateFilterableAttributesWithContext(ctx context.Context, request *[]interface{}) (*TaskInfo, error) {
460460
resp := new(TaskInfo)
461461
req := &internalRequest{
462462
endpoint: "/indexes/" + i.uid + "/settings/filterable-attributes",

0 commit comments

Comments
 (0)