github.com/opensearch-project/opensearch-go/v2@v2.3.0/opensearchapi/api.mget.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // 3 // The OpenSearch Contributors require contributions made to 4 // this file be licensed under the Apache-2.0 license or a 5 // compatible open source license. 6 // 7 // Modifications Copyright OpenSearch Contributors. See 8 // GitHub history for details. 9 10 // Licensed to Elasticsearch B.V. under one or more contributor 11 // license agreements. See the NOTICE file distributed with 12 // this work for additional information regarding copyright 13 // ownership. Elasticsearch B.V. licenses this file to you under 14 // the Apache License, Version 2.0 (the "License"); you may 15 // not use this file except in compliance with the License. 16 // You may obtain a copy of the License at 17 // 18 // http://www.apache.org/licenses/LICENSE-2.0 19 // 20 // Unless required by applicable law or agreed to in writing, 21 // software distributed under the License is distributed on an 22 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 23 // KIND, either express or implied. See the License for the 24 // specific language governing permissions and limitations 25 // under the License. 26 27 package opensearchapi 28 29 import ( 30 "context" 31 "io" 32 "net/http" 33 "strconv" 34 "strings" 35 ) 36 37 func newMgetFunc(t Transport) Mget { 38 return func(body io.Reader, o ...func(*MgetRequest)) (*Response, error) { 39 var r = MgetRequest{Body: body} 40 for _, f := range o { 41 f(&r) 42 } 43 return r.Do(r.ctx, t) 44 } 45 } 46 47 // ----- API Definition ------------------------------------------------------- 48 49 // Mget allows to get multiple documents in one request. 50 // 51 // 52 type Mget func(body io.Reader, o ...func(*MgetRequest)) (*Response, error) 53 54 // MgetRequest configures the Mget API request. 55 // 56 type MgetRequest struct { 57 Index string 58 59 Body io.Reader 60 61 Preference string 62 Realtime *bool 63 Refresh *bool 64 Routing string 65 Source interface{} 66 SourceExcludes []string 67 SourceIncludes []string 68 StoredFields []string 69 70 Pretty bool 71 Human bool 72 ErrorTrace bool 73 FilterPath []string 74 75 Header http.Header 76 77 ctx context.Context 78 } 79 80 // Do executes the request and returns response or error. 81 // 82 func (r MgetRequest) Do(ctx context.Context, transport Transport) (*Response, error) { 83 var ( 84 method string 85 path strings.Builder 86 params map[string]string 87 ) 88 89 method = "POST" 90 91 path.Grow(1 + len(r.Index) + 1 + len("_mget")) 92 if r.Index != "" { 93 path.WriteString("/") 94 path.WriteString(r.Index) 95 } 96 path.WriteString("/") 97 path.WriteString("_mget") 98 99 params = make(map[string]string) 100 101 if r.Preference != "" { 102 params["preference"] = r.Preference 103 } 104 105 if r.Realtime != nil { 106 params["realtime"] = strconv.FormatBool(*r.Realtime) 107 } 108 109 if r.Refresh != nil { 110 params["refresh"] = strconv.FormatBool(*r.Refresh) 111 } 112 113 if r.Routing != "" { 114 params["routing"] = r.Routing 115 } 116 117 if source, ok := r.Source.(bool); ok { 118 params["_source"] = strconv.FormatBool(source) 119 } else if source, ok := r.Source.(string); ok && source != "" { 120 params["_source"] = source 121 } else if sources, ok := r.Source.([]string); ok && len(sources) > 0 { 122 params["_source"] = strings.Join(sources, ",") 123 } 124 125 if len(r.SourceExcludes) > 0 { 126 params["_source_excludes"] = strings.Join(r.SourceExcludes, ",") 127 } 128 129 if len(r.SourceIncludes) > 0 { 130 params["_source_includes"] = strings.Join(r.SourceIncludes, ",") 131 } 132 133 if len(r.StoredFields) > 0 { 134 params["stored_fields"] = strings.Join(r.StoredFields, ",") 135 } 136 137 if r.Pretty { 138 params["pretty"] = "true" 139 } 140 141 if r.Human { 142 params["human"] = "true" 143 } 144 145 if r.ErrorTrace { 146 params["error_trace"] = "true" 147 } 148 149 if len(r.FilterPath) > 0 { 150 params["filter_path"] = strings.Join(r.FilterPath, ",") 151 } 152 153 req, err := newRequest(method, path.String(), r.Body) 154 if err != nil { 155 return nil, err 156 } 157 158 if len(params) > 0 { 159 q := req.URL.Query() 160 for k, v := range params { 161 q.Set(k, v) 162 } 163 req.URL.RawQuery = q.Encode() 164 } 165 166 if r.Body != nil { 167 req.Header[headerContentType] = headerContentTypeJSON 168 } 169 170 if len(r.Header) > 0 { 171 if len(req.Header) == 0 { 172 req.Header = r.Header 173 } else { 174 for k, vv := range r.Header { 175 for _, v := range vv { 176 req.Header.Add(k, v) 177 } 178 } 179 } 180 } 181 182 if ctx != nil { 183 req = req.WithContext(ctx) 184 } 185 186 res, err := transport.Perform(req) 187 if err != nil { 188 return nil, err 189 } 190 191 response := Response{ 192 StatusCode: res.StatusCode, 193 Body: res.Body, 194 Header: res.Header, 195 } 196 197 return &response, nil 198 } 199 200 // WithContext sets the request context. 201 // 202 func (f Mget) WithContext(v context.Context) func(*MgetRequest) { 203 return func(r *MgetRequest) { 204 r.ctx = v 205 } 206 } 207 208 // WithIndex - the name of the index. 209 // 210 func (f Mget) WithIndex(v string) func(*MgetRequest) { 211 return func(r *MgetRequest) { 212 r.Index = v 213 } 214 } 215 216 // WithPreference - specify the node or shard the operation should be performed on (default: random). 217 // 218 func (f Mget) WithPreference(v string) func(*MgetRequest) { 219 return func(r *MgetRequest) { 220 r.Preference = v 221 } 222 } 223 224 // WithRealtime - specify whether to perform the operation in realtime or search mode. 225 // 226 func (f Mget) WithRealtime(v bool) func(*MgetRequest) { 227 return func(r *MgetRequest) { 228 r.Realtime = &v 229 } 230 } 231 232 // WithRefresh - refresh the shard containing the document before performing the operation. 233 // 234 func (f Mget) WithRefresh(v bool) func(*MgetRequest) { 235 return func(r *MgetRequest) { 236 r.Refresh = &v 237 } 238 } 239 240 // WithRouting - specific routing value. 241 // 242 func (f Mget) WithRouting(v string) func(*MgetRequest) { 243 return func(r *MgetRequest) { 244 r.Routing = v 245 } 246 } 247 248 // WithSource - true or false to return the _source field or not, or a list of fields to return. 249 // 250 func (f Mget) WithSource(v interface{}) func(*MgetRequest) { 251 return func(r *MgetRequest) { 252 r.Source = v 253 } 254 } 255 256 // WithSourceExcludes - a list of fields to exclude from the returned _source field. 257 // 258 func (f Mget) WithSourceExcludes(v ...string) func(*MgetRequest) { 259 return func(r *MgetRequest) { 260 r.SourceExcludes = v 261 } 262 } 263 264 // WithSourceIncludes - a list of fields to extract and return from the _source field. 265 // 266 func (f Mget) WithSourceIncludes(v ...string) func(*MgetRequest) { 267 return func(r *MgetRequest) { 268 r.SourceIncludes = v 269 } 270 } 271 272 // WithStoredFields - a list of stored fields to return in the response. 273 // 274 func (f Mget) WithStoredFields(v ...string) func(*MgetRequest) { 275 return func(r *MgetRequest) { 276 r.StoredFields = v 277 } 278 } 279 280 // WithPretty makes the response body pretty-printed. 281 // 282 func (f Mget) WithPretty() func(*MgetRequest) { 283 return func(r *MgetRequest) { 284 r.Pretty = true 285 } 286 } 287 288 // WithHuman makes statistical values human-readable. 289 // 290 func (f Mget) WithHuman() func(*MgetRequest) { 291 return func(r *MgetRequest) { 292 r.Human = true 293 } 294 } 295 296 // WithErrorTrace includes the stack trace for errors in the response body. 297 // 298 func (f Mget) WithErrorTrace() func(*MgetRequest) { 299 return func(r *MgetRequest) { 300 r.ErrorTrace = true 301 } 302 } 303 304 // WithFilterPath filters the properties of the response body. 305 // 306 func (f Mget) WithFilterPath(v ...string) func(*MgetRequest) { 307 return func(r *MgetRequest) { 308 r.FilterPath = v 309 } 310 } 311 312 // WithHeader adds the headers to the HTTP request. 313 // 314 func (f Mget) WithHeader(h map[string]string) func(*MgetRequest) { 315 return func(r *MgetRequest) { 316 if r.Header == nil { 317 r.Header = make(http.Header) 318 } 319 for k, v := range h { 320 r.Header.Add(k, v) 321 } 322 } 323 } 324 325 // WithOpaqueID adds the X-Opaque-Id header to the HTTP request. 326 // 327 func (f Mget) WithOpaqueID(s string) func(*MgetRequest) { 328 return func(r *MgetRequest) { 329 if r.Header == nil { 330 r.Header = make(http.Header) 331 } 332 r.Header.Set("X-Opaque-Id", s) 333 } 334 }