1// Copyright 2012-present Oliver Eilhard. All rights reserved. 2// Use of this source code is governed by a MIT-license. 3// See http://olivere.mit-license.org/license.txt for details. 4 5package elastic 6 7import ( 8 "context" 9 "encoding/json" 10 "fmt" 11 "net/url" 12 "strings" 13) 14 15// MultiSearch executes one or more searches in one roundtrip. 16type MultiSearchService struct { 17 client *Client 18 requests []*SearchRequest 19 indices []string 20 pretty bool 21 routing string 22 preference string 23} 24 25func NewMultiSearchService(client *Client) *MultiSearchService { 26 builder := &MultiSearchService{ 27 client: client, 28 requests: make([]*SearchRequest, 0), 29 indices: make([]string, 0), 30 } 31 return builder 32} 33 34func (s *MultiSearchService) Add(requests ...*SearchRequest) *MultiSearchService { 35 s.requests = append(s.requests, requests...) 36 return s 37} 38 39func (s *MultiSearchService) Index(indices ...string) *MultiSearchService { 40 s.indices = append(s.indices, indices...) 41 return s 42} 43 44func (s *MultiSearchService) Pretty(pretty bool) *MultiSearchService { 45 s.pretty = pretty 46 return s 47} 48 49func (s *MultiSearchService) Do(ctx context.Context) (*MultiSearchResult, error) { 50 // Build url 51 path := "/_msearch" 52 53 // Parameters 54 params := make(url.Values) 55 if s.pretty { 56 params.Set("pretty", fmt.Sprintf("%v", s.pretty)) 57 } 58 59 // Set body 60 var lines []string 61 for _, sr := range s.requests { 62 // Set default indices if not specified in the request 63 if !sr.HasIndices() && len(s.indices) > 0 { 64 sr = sr.Index(s.indices...) 65 } 66 67 header, err := json.Marshal(sr.header()) 68 if err != nil { 69 return nil, err 70 } 71 body, err := json.Marshal(sr.Body()) 72 if err != nil { 73 return nil, err 74 } 75 lines = append(lines, string(header)) 76 lines = append(lines, string(body)) 77 } 78 body := strings.Join(lines, "\n") + "\n" // Don't forget trailing \n 79 80 // Get response 81 res, err := s.client.PerformRequest(ctx, "GET", path, params, body) 82 if err != nil { 83 return nil, err 84 } 85 86 // Return result 87 ret := new(MultiSearchResult) 88 if err := s.client.decoder.Decode(res.Body, ret); err != nil { 89 return nil, err 90 } 91 return ret, nil 92} 93 94type MultiSearchResult struct { 95 Responses []*SearchResult `json:"responses,omitempty"` 96} 97