Skip to content

Commit

Permalink
fix: Search fixes
Browse files Browse the repository at this point in the history
* Add GetOne / DeleteOne APIs
* Properly handle empty results, returned for not found entries
* Use sort.Order by value
  (Allows to use it in-place do not require to precreate variable)
* Test map[string]any
  • Loading branch information
efirs committed Apr 3, 2023
1 parent 6cba0b4 commit 01e5a4f
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 8 deletions.
6 changes: 4 additions & 2 deletions schema/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ func TestCollectionSchema(t *testing.T) {
Slice2 []subStruct `json:"slice_2"`
Map2 map[string]subStruct `json:"map_2"`
Data2 subStructPK `json:"data_2" tigris:"-"` // should be skipped
MapAny map[string]any `json:"map_any"`

Bool123 bool `json:"bool_123"`

Expand Down Expand Up @@ -304,7 +305,8 @@ func TestCollectionSchema(t *testing.T) {
},
},
},
"map_2": {Type: typeObject, AdditionalProperties: true},
"map_2": {Type: typeObject, AdditionalProperties: true},
"map_any": {Type: typeObject, AdditionalProperties: true},

// use original name if JSON tag name is not defined
"bool_123": {Type: typeBoolean},
Expand Down Expand Up @@ -404,7 +406,7 @@ func TestCollectionSchema(t *testing.T) {
b, err := s.Build()
require.NoError(t, err)

require.Equal(t, `{"title":"all_types","properties":{"PtrStruct":{"type":"object","properties":{"ss_field_1":{"type":"string"}}},"Tm":{"type":"string","format":"date-time"},"TmPtr":{"type":"string","format":"date-time"},"UUID":{"type":"string","format":"uuid"},"UUIDPtr":{"type":"string","format":"uuid"},"arr_1":{"type":"array","items":{"type":"string"}},"bool_1":{"type":"boolean"},"bool_123":{"type":"boolean"},"bytes_1":{"type":"string","format":"byte"},"bytes_2":{"type":"string","format":"byte"},"data_1":{"type":"object","properties":{"Nested":{"type":"object","properties":{"ss_field_1":{"type":"string"}}},"field_1":{"type":"string"}}},"float_32":{"type":"number"},"float_64":{"type":"number"},"int_1":{"type":"integer"},"int_32":{"type":"integer","format":"int32"},"int_64":{"type":"integer"},"map_1":{"type":"object","additionalProperties":true},"map_2":{"type":"object","additionalProperties":true},"slice_1":{"type":"array","items":{"type":"string"}},"slice_2":{"type":"array","items":{"type":"object","properties":{"Nested":{"type":"object","properties":{"ss_field_1":{"type":"string"}}},"field_1":{"type":"string"}}}},"string_1":{"type":"string"}},"primary_key":["string_1"]}`, string(b))
require.Equal(t, `{"title":"all_types","properties":{"PtrStruct":{"type":"object","properties":{"ss_field_1":{"type":"string"}}},"Tm":{"type":"string","format":"date-time"},"TmPtr":{"type":"string","format":"date-time"},"UUID":{"type":"string","format":"uuid"},"UUIDPtr":{"type":"string","format":"uuid"},"arr_1":{"type":"array","items":{"type":"string"}},"bool_1":{"type":"boolean"},"bool_123":{"type":"boolean"},"bytes_1":{"type":"string","format":"byte"},"bytes_2":{"type":"string","format":"byte"},"data_1":{"type":"object","properties":{"Nested":{"type":"object","properties":{"ss_field_1":{"type":"string"}}},"field_1":{"type":"string"}}},"float_32":{"type":"number"},"float_64":{"type":"number"},"int_1":{"type":"integer"},"int_32":{"type":"integer","format":"int32"},"int_64":{"type":"integer"},"map_1":{"type":"object","additionalProperties":true},"map_2":{"type":"object","additionalProperties":true},"map_any":{"type":"object","additionalProperties":true},"slice_1":{"type":"array","items":{"type":"string"}},"slice_2":{"type":"array","items":{"type":"object","properties":{"Nested":{"type":"object","properties":{"ss_field_1":{"type":"string"}}},"field_1":{"type":"string"}}}},"string_1":{"type":"string"}},"primary_key":["string_1"]}`, string(b))
})

t.Run("multiple_models", func(t *testing.T) {
Expand Down
20 changes: 20 additions & 0 deletions search/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ func (c *Index[T]) Get(ctx context.Context, ids []string) ([]T, error) {
for _, v := range resp {
var doc T

if v.Data == nil {
continue
}

err = json.Unmarshal(v.Data, &doc)
if err != nil {
return nil, err
Expand All @@ -144,6 +148,16 @@ func (c *Index[T]) Get(ctx context.Context, ids []string) ([]T, error) {
return docs, nil
}

// GetOne retrieves one document.
func (c *Index[T]) GetOne(ctx context.Context, id string) (*T, error) {
docs, err := c.Get(ctx, []string{id})
if err != nil {
return nil, err
}

return &docs[0], nil
}

func getSearchRequest(req *Request) (*driver.SearchRequest, error) {
if req == nil {
return nil, fmt.Errorf("search request cannot be null")
Expand Down Expand Up @@ -222,6 +236,12 @@ func (c *Index[T]) Delete(ctx context.Context, ids []string) (*Response, error)
return &Response{Statuses: setStatuses(resp)}, nil
}

// DeleteOne deletes one document.
func (c *Index[T]) DeleteOne(ctx context.Context, id string) error {
_, err := c.Delete(ctx, []string{id})
return err
}

// DeleteByQuery is used to delete documents that match the filter. A filter is required. To delete document by id,
// you can pass the filter as follows ```{"id": "test"}```. Returns a count of number of documents deleted.
func (c *Index[T]) DeleteByQuery(ctx context.Context, filter filter.Filter) (int, error) {
Expand Down
37 changes: 37 additions & 0 deletions search/index_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,32 @@ func TestSearchIndex_DocumentCRUDIndex(t *testing.T) {
require.Equal(t, tm, d[0].GetUpdatedAt())
})

t.Run("get_not_found", func(t *testing.T) {
msearch.EXPECT().Get(gomock.Any(), "coll_search_tests", []string{"id1"}).Return(
[]*api.SearchHit{{Data: nil, Metadata: nil}}, // server return empty result for every not found id
nil)

d, err := idx.Get(ctx, []string{"id1"})
require.NoError(t, err)
require.Equal(t, []CollSearchTest{}, d)
})

t.Run("get_one", func(t *testing.T) {
msearch.EXPECT().Get(gomock.Any(), "coll_search_tests", []string{"id1"}).Return(
[]*api.SearchHit{{Data: toDocument(t, d1), Metadata: &api.SearchHitMeta{
CreatedAt: timestamppb.New(tm),
UpdatedAt: timestamppb.New(tm),
}}}, nil)

d, err := idx.GetOne(ctx, "id1")
require.NoError(t, err)
require.Equal(t, &CollSearchTest{
Field1: "value1",
Metadata: newMetadata(tm, tm),
}, d)
require.Equal(t, tm, d.GetCreatedAt())
})

t.Run("create", func(t *testing.T) {
msearch.EXPECT().Create(gomock.Any(), "coll_search_tests", []driver.Document{toDocument(t, d1), toDocument(t, d2)}).
Return(
Expand Down Expand Up @@ -150,6 +176,17 @@ func TestSearchIndex_DocumentCRUDIndex(t *testing.T) {
}, resp)
})

t.Run("delete_one", func(t *testing.T) {
msearch.EXPECT().Delete(gomock.Any(), "coll_search_tests", []string{"id1"}).
Return(
[]*api.DocStatus{
{Id: "id1", Error: nil},
}, nil)

err := idx.DeleteOne(ctx, "id1")
require.NoError(t, err)
})

t.Run("delete_by_query", func(t *testing.T) {
msearch.EXPECT().DeleteByQuery(gomock.Any(), "coll_search_tests", driver.Filter(`{"all":{"$eq":"b"}}`)).
Return(int32(2), nil)
Expand Down
8 changes: 4 additions & 4 deletions search/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type Request struct {
// Optional Facet query can be used to request categorical arrangement of the indexed terms
Facet *FacetQuery
// Optional Sort order can be specified to order the search results
Sort *sort.Order
Sort sort.Order
// Optional IncludeFields sets the document fields to include in search results
// By default, all documents fields will be included, unless ExcludeFields is specified
IncludeFields []string
Expand Down Expand Up @@ -73,7 +73,7 @@ type requestBuilder struct {
searchFields map[string]bool
filter filter.Filter
facet *FacetQuery
sort *sort.Order
sort sort.Order
include []string
exclude []string
options *Options
Expand Down Expand Up @@ -114,13 +114,13 @@ func (b *requestBuilder) WithFacet(facet *FacetQuery) RequestBuilder {

func (b *requestBuilder) WithSorting(sortByFields ...sort.Sort) RequestBuilder {
s := sort.NewSortOrder(sortByFields...)
b.sort = &s
b.sort = s

return b
}

func (b *requestBuilder) WithSortOrder(sortOrder sort.Order) RequestBuilder {
b.sort = &sortOrder
b.sort = sortOrder

return b
}
Expand Down
4 changes: 2 additions & 2 deletions search/request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func TestRequestBuilder_Build(t *testing.T) {
req := NewRequestBuilder().
WithSorting(sort.Ascending("field_1"), sort.Descending("field_2")).
Build()
assert.Len(t, *req.Sort, 2)
assert.Len(t, req.Sort, 2)
b, err := req.Sort.Built()
assert.Nil(t, err)
assert.Equal(t, driver.SortOrder(`[{"field_1":"$asc"},{"field_2":"$desc"}]`), b)
Expand All @@ -84,7 +84,7 @@ func TestRequestBuilder_Build(t *testing.T) {
req := NewRequestBuilder().
WithSortOrder(order).
Build()
assert.Equal(t, &order, req.Sort)
assert.Equal(t, order, req.Sort)
})
}

Expand Down

0 comments on commit 01e5a4f

Please sign in to comment.