Skip to content

Commit 9c5f231

Browse files
MaximMolchanov17sushmita
authored andcommitted
Inner hits support (opensearch-project#672)
* Inner hits support Signed-off-by: Maxim Molchanov <[email protected]> * Fix Signed-off-by: Maxim Molchanov <[email protected]> * Changelog update Signed-off-by: Maxim Molchanov <[email protected]> --------- Signed-off-by: Maxim Molchanov <[email protected]> Signed-off-by: 17sushmita <[email protected]>
1 parent 40a70f3 commit 9c5f231

File tree

3 files changed

+69
-18
lines changed

3 files changed

+69
-18
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
55
## [Unreleased]
66
### Dependencies
77
### Added
8+
- Adds `InnerHits` field to `SearchResp` ([#672](https://github.com/opensearch-project/opensearch-go/pull/672))
9+
810
### Changed
911
### Deprecated
1012
### Removed

opensearchapi/api_search.go

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,10 @@ func (r SearchReq) GetRequest() (*http.Request, error) {
6363

6464
// SearchResp represents the returned struct of the /_search response
6565
type SearchResp struct {
66-
Took int `json:"took"`
67-
Timeout bool `json:"timed_out"`
68-
Shards ResponseShards `json:"_shards"`
69-
Hits struct {
70-
Total struct {
71-
Value int `json:"value"`
72-
Relation string `json:"relation"`
73-
} `json:"total"`
74-
MaxScore float32 `json:"max_score"`
75-
Hits []SearchHit `json:"hits"`
76-
} `json:"hits"`
66+
Took int `json:"took"`
67+
Timeout bool `json:"timed_out"`
68+
Shards ResponseShards `json:"_shards"`
69+
Hits SearchHits `json:"hits"`
7770
Errors bool `json:"errors"`
7871
Aggregations json.RawMessage `json:"aggregations"`
7972
ScrollID *string `json:"_scroll_id,omitempty"`
@@ -86,14 +79,27 @@ func (r SearchResp) Inspect() Inspect {
8679
return Inspect{Response: r.response}
8780
}
8881

82+
// SearchHits is a list of SearchHit with Total and MaxScore fields
83+
type SearchHits struct {
84+
Total struct {
85+
Value int `json:"value"`
86+
Relation string `json:"relation"`
87+
} `json:"total"`
88+
MaxScore float32 `json:"max_score"`
89+
Hits []SearchHit `json:"hits"`
90+
}
91+
8992
// SearchHit is a sub type of SearchResp containing information of the search hit with an unparsed Source field
9093
type SearchHit struct {
91-
Index string `json:"_index"`
92-
ID string `json:"_id"`
93-
Routing string `json:"_routing"`
94-
Score float32 `json:"_score"`
95-
Source json.RawMessage `json:"_source"`
96-
Fields json.RawMessage `json:"fields"`
94+
Index string `json:"_index"`
95+
ID string `json:"_id"`
96+
Routing string `json:"_routing"`
97+
Score float32 `json:"_score"`
98+
Source json.RawMessage `json:"_source"`
99+
Fields json.RawMessage `json:"fields"`
100+
InnerHits map[string]struct {
101+
Hits SearchHits `json:"hits"`
102+
} `json:"inner_hits"`
97103
Type string `json:"_type"` // Deprecated field
98104
Sort []any `json:"sort"`
99105
Explanation *DocumentExplainDetails `json:"_explanation"`

opensearchapi/api_search_test.go

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,28 @@ func TestSearch(t *testing.T) {
2727

2828
index := "test-index-search"
2929

30+
_, err = client.Indices.Create(
31+
nil,
32+
opensearchapi.IndicesCreateReq{
33+
Index: index,
34+
Body: strings.NewReader(`{
35+
"mappings": {
36+
"properties": {
37+
"baz": {
38+
"type": "nested"
39+
}
40+
}
41+
}
42+
}`),
43+
},
44+
)
45+
require.Nil(t, err)
3046
_, err = client.Index(
3147
nil,
3248
opensearchapi.IndexReq{
3349
DocumentID: "foo",
3450
Index: index,
35-
Body: strings.NewReader(`{"foo": "bar"}`),
51+
Body: strings.NewReader(`{"foo": "bar", "baz": [{"foo": "test"}]}`),
3652
Params: opensearchapi.IndexParams{Refresh: "true", Routing: "foo"},
3753
},
3854
)
@@ -227,4 +243,31 @@ func TestSearch(t *testing.T) {
227243
assert.NotEmpty(t, resp.Hits.Hits)
228244
assert.Equal(t, []string{"test"}, resp.Hits.Hits[0].MatchedQueries)
229245
})
246+
247+
t.Run("request with inner hits", func(t *testing.T) {
248+
resp, err := client.Search(
249+
nil,
250+
&opensearchapi.SearchReq{
251+
Indices: []string{index},
252+
Body: strings.NewReader(`{
253+
"query": {
254+
"nested": {
255+
"path": "baz",
256+
"query": {
257+
"match": {
258+
"baz.foo": "test"
259+
}
260+
},
261+
"inner_hits": {}
262+
}
263+
}
264+
}`),
265+
},
266+
)
267+
require.Nil(t, err)
268+
assert.NotEmpty(t, resp.Hits.Hits)
269+
assert.NotEmpty(t, resp.Hits.Hits[0].InnerHits)
270+
assert.NotNil(t, resp.Hits.Hits[0].InnerHits["baz"])
271+
assert.NotEmpty(t, resp.Hits.Hits[0].InnerHits["baz"].Hits.Hits)
272+
})
230273
}

0 commit comments

Comments
 (0)