msearch.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. package elastic
  5. import (
  6. "context"
  7. "encoding/json"
  8. "fmt"
  9. "net/url"
  10. "strings"
  11. )
  12. // MultiSearch executes one or more searches in one roundtrip.
  13. type MultiSearchService struct {
  14. client *Client
  15. requests []*SearchRequest
  16. indices []string
  17. pretty bool
  18. maxConcurrentRequests *int
  19. preFilterShardSize *int
  20. }
  21. func NewMultiSearchService(client *Client) *MultiSearchService {
  22. builder := &MultiSearchService{
  23. client: client,
  24. }
  25. return builder
  26. }
  27. func (s *MultiSearchService) Add(requests ...*SearchRequest) *MultiSearchService {
  28. s.requests = append(s.requests, requests...)
  29. return s
  30. }
  31. func (s *MultiSearchService) Index(indices ...string) *MultiSearchService {
  32. s.indices = append(s.indices, indices...)
  33. return s
  34. }
  35. func (s *MultiSearchService) Pretty(pretty bool) *MultiSearchService {
  36. s.pretty = pretty
  37. return s
  38. }
  39. func (s *MultiSearchService) MaxConcurrentSearches(max int) *MultiSearchService {
  40. s.maxConcurrentRequests = &max
  41. return s
  42. }
  43. func (s *MultiSearchService) PreFilterShardSize(size int) *MultiSearchService {
  44. s.preFilterShardSize = &size
  45. return s
  46. }
  47. func (s *MultiSearchService) Do(ctx context.Context) (*MultiSearchResult, error) {
  48. // Build url
  49. path := "/_msearch"
  50. // Parameters
  51. params := make(url.Values)
  52. if s.pretty {
  53. params.Set("pretty", fmt.Sprintf("%v", s.pretty))
  54. }
  55. if v := s.maxConcurrentRequests; v != nil {
  56. params.Set("max_concurrent_searches", fmt.Sprintf("%v", *v))
  57. }
  58. if v := s.preFilterShardSize; v != nil {
  59. params.Set("pre_filter_shard_size", fmt.Sprintf("%v", *v))
  60. }
  61. // Set body
  62. var lines []string
  63. for _, sr := range s.requests {
  64. // Set default indices if not specified in the request
  65. if !sr.HasIndices() && len(s.indices) > 0 {
  66. sr = sr.Index(s.indices...)
  67. }
  68. header, err := json.Marshal(sr.header())
  69. if err != nil {
  70. return nil, err
  71. }
  72. body, err := sr.Body()
  73. if err != nil {
  74. return nil, err
  75. }
  76. lines = append(lines, string(header))
  77. lines = append(lines, body)
  78. }
  79. body := strings.Join(lines, "\n") + "\n" // add trailing \n
  80. // Get response
  81. res, err := s.client.PerformRequest(ctx, "GET", path, params, body)
  82. if err != nil {
  83. return nil, err
  84. }
  85. // Return result
  86. ret := new(MultiSearchResult)
  87. if err := s.client.decoder.Decode(res.Body, ret); err != nil {
  88. return nil, err
  89. }
  90. return ret, nil
  91. }
  92. // MultiSearchResult is the outcome of running a multi-search operation.
  93. type MultiSearchResult struct {
  94. Responses []*SearchResult `json:"responses,omitempty"`
  95. }