Skip to content

Commit

Permalink
add SearchRaw to return raw JSON from search
Browse files Browse the repository at this point in the history
adds a method SearchRaw with the same signature as
SearchIndex except it returns json.RawMessage
  • Loading branch information
ginglis13 committed Oct 26, 2022
1 parent 995541c commit 7dbefd4
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 38 deletions.
2 changes: 2 additions & 0 deletions index.go
@@ -1,6 +1,7 @@
package meilisearch

import (
"encoding/json"
"net/http"
"strconv"
"strings"
Expand Down Expand Up @@ -38,6 +39,7 @@ type IndexInterface interface {
DeleteDocuments(uid []string) (resp *TaskInfo, err error)
DeleteAllDocuments() (resp *TaskInfo, err error)
Search(query string, request *SearchRequest) (*SearchResponse, error)
SearchRaw(query string, request *SearchRequest) (*json.RawMessage, error)

GetTask(taskUID int64) (resp *Task, err error)
GetTasks(param *TasksQuery) (resp *TaskResult, err error)
Expand Down
97 changes: 65 additions & 32 deletions index_search.go
@@ -1,6 +1,7 @@
package meilisearch

import (
"encoding/json"
"net/http"
)

Expand All @@ -11,74 +12,106 @@ const (
DefaultLimit int64 = 20
)

func (i Index) SearchRaw(query string, request *SearchRequest) (*json.RawMessage, error) {
resp := &json.RawMessage{}

if request.Limit == 0 {
request.Limit = DefaultLimit
}

searchPostRequestParams := searchPostRequestParams(query, request)

req := internalRequest{
endpoint: "/indexes/" + i.UID + "/search",
method: http.MethodPost,
contentType: contentTypeJSON,
withRequest: searchPostRequestParams,
withResponse: resp,
acceptedStatusCodes: []int{http.StatusOK},
functionName: "SearchRaw",
}

if err := i.client.executeRequest(req); err != nil {
return nil, err
}

return resp, nil
}

func (i Index) Search(query string, request *SearchRequest) (*SearchResponse, error) {
resp := &SearchResponse{}

searchPostRequestParams := make(map[string]interface{}, 14)

if request.Limit == 0 {
request.Limit = DefaultLimit
}

searchPostRequestParams := searchPostRequestParams(query, request)

req := internalRequest{
endpoint: "/indexes/" + i.UID + "/search",
method: http.MethodPost,
contentType: contentTypeJSON,
withRequest: searchPostRequestParams,
withResponse: resp,
acceptedStatusCodes: []int{http.StatusOK},
functionName: "Search",
}

if err := i.client.executeRequest(req); err != nil {
return nil, err
}

return resp, nil
}

func searchPostRequestParams(query string, request *SearchRequest) map[string]interface{} {
params := make(map[string]interface{}, 14)

if !request.PlaceholderSearch {
searchPostRequestParams["q"] = query
params["q"] = query
}
if request.Limit != DefaultLimit {
searchPostRequestParams["limit"] = request.Limit
params["limit"] = request.Limit
}
if request.ShowMatchesPosition {
searchPostRequestParams["showMatchesPosition"] = request.ShowMatchesPosition
params["showMatchesPosition"] = request.ShowMatchesPosition
}
if request.Filter != nil {
searchPostRequestParams["filter"] = request.Filter
params["filter"] = request.Filter
}
if request.Offset != 0 {
searchPostRequestParams["offset"] = request.Offset
params["offset"] = request.Offset
}
if request.CropLength != 0 {
searchPostRequestParams["cropLength"] = request.CropLength
params["cropLength"] = request.CropLength
}
if request.CropMarker != "" {
searchPostRequestParams["cropMarker"] = request.CropMarker
params["cropMarker"] = request.CropMarker
}
if request.HighlightPreTag != "" {
searchPostRequestParams["highlightPreTag"] = request.HighlightPreTag
params["highlightPreTag"] = request.HighlightPreTag
}
if request.HighlightPostTag != "" {
searchPostRequestParams["highlightPostTag"] = request.HighlightPostTag
params["highlightPostTag"] = request.HighlightPostTag
}
if request.MatchingStrategy != "" {
searchPostRequestParams["matchingStrategy"] = request.MatchingStrategy
params["matchingStrategy"] = request.MatchingStrategy
}
if len(request.AttributesToRetrieve) != 0 {
searchPostRequestParams["attributesToRetrieve"] = request.AttributesToRetrieve
params["attributesToRetrieve"] = request.AttributesToRetrieve
}
if len(request.AttributesToCrop) != 0 {
searchPostRequestParams["attributesToCrop"] = request.AttributesToCrop
params["attributesToCrop"] = request.AttributesToCrop
}
if len(request.AttributesToHighlight) != 0 {
searchPostRequestParams["attributesToHighlight"] = request.AttributesToHighlight
params["attributesToHighlight"] = request.AttributesToHighlight
}
if len(request.Facets) != 0 {
searchPostRequestParams["facets"] = request.Facets
params["facets"] = request.Facets
}
if len(request.Sort) != 0 {
searchPostRequestParams["sort"] = request.Sort
}

req := internalRequest{
endpoint: "/indexes/" + i.UID + "/search",
method: http.MethodPost,
contentType: contentTypeJSON,
withRequest: searchPostRequestParams,
withResponse: resp,
acceptedStatusCodes: []int{http.StatusOK},
functionName: "Search",
params["sort"] = request.Sort
}

if err := i.client.executeRequest(req); err != nil {
return nil, err
}

return resp, nil
return params
}
81 changes: 75 additions & 6 deletions index_search_test.go
@@ -1,11 +1,80 @@
package meilisearch

import (
"encoding/json"
"testing"

"github.com/stretchr/testify/require"
)

func TestIndex_SearchRaw(t *testing.T) {
type args struct {
UID string
PrimaryKey string
client *Client
query string
request SearchRequest
}

tests := []struct {
name string
args args
want *SearchResponse
}{
{
name: "TestIndexBasicSearch",
args: args{
UID: "indexUID",
client: defaultClient,
query: "prince",
request: SearchRequest{},
},
want: &SearchResponse{
Hits: []interface{}{
map[string]interface{}{
"book_id": float64(456), "title": "Le Petit Prince",
},
map[string]interface{}{
"Tag": "Epic fantasy", "book_id": float64(4), "title": "Harry Potter and the Half-Blood Prince",
},
},
EstimatedTotalHits: 2,
Offset: 0,
Limit: 20,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
SetUpIndexForFaceting()
c := tt.args.client
i := c.Index(tt.args.UID)
t.Cleanup(cleanup(c))

gotRaw, err := i.SearchRaw(tt.args.query, &tt.args.request)
require.NoError(t, err)

// Unmarshall the raw response from SearchRaw into a SearchResponse
var got SearchResponse
err = json.Unmarshal(*gotRaw, &got)
require.NoError(t, err, "error unmarshalling raw got SearchResponse")

require.Equal(t, len(tt.want.Hits), len(got.Hits))
for len := range got.Hits {
require.Equal(t, tt.want.Hits[len].(map[string]interface{})["title"], got.Hits[len].(map[string]interface{})["title"])
require.Equal(t, tt.want.Hits[len].(map[string]interface{})["book_id"], got.Hits[len].(map[string]interface{})["book_id"])
}
if tt.want.Hits[0].(map[string]interface{})["_formatted"] != nil {
require.Equal(t, tt.want.Hits[0].(map[string]interface{})["_formatted"], got.Hits[0].(map[string]interface{})["_formatted"])
}
require.Equal(t, tt.want.EstimatedTotalHits, got.EstimatedTotalHits)
require.Equal(t, tt.want.Offset, got.Offset)
require.Equal(t, tt.want.Limit, got.Limit)
require.Equal(t, tt.want.FacetDistribution, got.FacetDistribution)
})
}
}

func TestIndex_Search(t *testing.T) {
type args struct {
UID string
Expand Down Expand Up @@ -309,9 +378,9 @@ func TestIndex_Search(t *testing.T) {
client: defaultClient,
query: "le prince",
request: SearchRequest{
Limit: 10,
AttributesToRetrieve: []string{"book_id","title"},
MatchingStrategy: "all",
Limit: 10,
AttributesToRetrieve: []string{"book_id", "title"},
MatchingStrategy: "all",
},
},
want: &SearchResponse{
Expand All @@ -332,9 +401,9 @@ func TestIndex_Search(t *testing.T) {
client: defaultClient,
query: "prince",
request: SearchRequest{
Limit: 10,
AttributesToRetrieve: []string{"book_id","title"},
MatchingStrategy: "last",
Limit: 10,
AttributesToRetrieve: []string{"book_id", "title"},
MatchingStrategy: "last",
},
},
want: &SearchResponse{
Expand Down

0 comments on commit 7dbefd4

Please sign in to comment.