field_caps.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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. "fmt"
  8. "net/http"
  9. "net/url"
  10. "strings"
  11. "gopkg.in/olivere/elastic.v5/uritemplates"
  12. )
  13. // FieldCapsService allows retrieving the capabilities of fields among multiple indices.
  14. //
  15. // See http://www.elastic.co/guide/en/elasticsearch/reference/5.x/search-field-caps.html
  16. // for details
  17. type FieldCapsService struct {
  18. client *Client
  19. pretty bool
  20. index []string
  21. allowNoIndices *bool
  22. expandWildcards string
  23. fields []string
  24. ignoreUnavailable *bool
  25. bodyJson interface{}
  26. bodyString string
  27. }
  28. // NewFieldCapsService creates a new FieldCapsService
  29. func NewFieldCapsService(client *Client) *FieldCapsService {
  30. return &FieldCapsService{
  31. client: client,
  32. }
  33. }
  34. // Index is a list of index names; use `_all` or empty string to perform
  35. // the operation on all indices.
  36. func (s *FieldCapsService) Index(index ...string) *FieldCapsService {
  37. s.index = append(s.index, index...)
  38. return s
  39. }
  40. // AllowNoIndices indicates whether to ignore if a wildcard indices expression
  41. // resolves into no concrete indices.
  42. // (This includes `_all` string or when no indices have been specified).
  43. func (s *FieldCapsService) AllowNoIndices(allowNoIndices bool) *FieldCapsService {
  44. s.allowNoIndices = &allowNoIndices
  45. return s
  46. }
  47. // ExpandWildcards indicates whether to expand wildcard expression to
  48. // concrete indices that are open, closed or both.
  49. func (s *FieldCapsService) ExpandWildcards(expandWildcards string) *FieldCapsService {
  50. s.expandWildcards = expandWildcards
  51. return s
  52. }
  53. // Fields is a list of fields for to get field capabilities.
  54. func (s *FieldCapsService) Fields(fields ...string) *FieldCapsService {
  55. s.fields = append(s.fields, fields...)
  56. return s
  57. }
  58. // IgnoreUnavailable is documented as: Whether specified concrete indices should be ignored when unavailable (missing or closed).
  59. func (s *FieldCapsService) IgnoreUnavailable(ignoreUnavailable bool) *FieldCapsService {
  60. s.ignoreUnavailable = &ignoreUnavailable
  61. return s
  62. }
  63. // Pretty indicates that the JSON response be indented and human readable.
  64. func (s *FieldCapsService) Pretty(pretty bool) *FieldCapsService {
  65. s.pretty = pretty
  66. return s
  67. }
  68. // BodyJson is documented as: Field json objects containing the name and optionally a range to filter out indices result, that have results outside the defined bounds.
  69. func (s *FieldCapsService) BodyJson(body interface{}) *FieldCapsService {
  70. s.bodyJson = body
  71. return s
  72. }
  73. // BodyString is documented as: Field json objects containing the name and optionally a range to filter out indices result, that have results outside the defined bounds.
  74. func (s *FieldCapsService) BodyString(body string) *FieldCapsService {
  75. s.bodyString = body
  76. return s
  77. }
  78. // buildURL builds the URL for the operation.
  79. func (s *FieldCapsService) buildURL() (string, url.Values, error) {
  80. // Build URL
  81. var err error
  82. var path string
  83. if len(s.index) > 0 {
  84. path, err = uritemplates.Expand("/{index}/_field_caps", map[string]string{
  85. "index": strings.Join(s.index, ","),
  86. })
  87. } else {
  88. path = "/_field_caps"
  89. }
  90. if err != nil {
  91. return "", url.Values{}, err
  92. }
  93. // Add query string parameters
  94. params := url.Values{}
  95. if s.pretty {
  96. params.Set("pretty", "true")
  97. }
  98. if s.allowNoIndices != nil {
  99. params.Set("allow_no_indices", fmt.Sprintf("%v", *s.allowNoIndices))
  100. }
  101. if s.expandWildcards != "" {
  102. params.Set("expand_wildcards", s.expandWildcards)
  103. }
  104. if len(s.fields) > 0 {
  105. params.Set("fields", strings.Join(s.fields, ","))
  106. }
  107. if s.ignoreUnavailable != nil {
  108. params.Set("ignore_unavailable", fmt.Sprintf("%v", *s.ignoreUnavailable))
  109. }
  110. return path, params, nil
  111. }
  112. // Validate checks if the operation is valid.
  113. func (s *FieldCapsService) Validate() error {
  114. return nil
  115. }
  116. // Do executes the operation.
  117. func (s *FieldCapsService) Do(ctx context.Context) (*FieldCapsResponse, error) {
  118. // Check pre-conditions
  119. if err := s.Validate(); err != nil {
  120. return nil, err
  121. }
  122. // Get URL for request
  123. path, params, err := s.buildURL()
  124. if err != nil {
  125. return nil, err
  126. }
  127. // Setup HTTP request body
  128. var body interface{}
  129. if s.bodyJson != nil {
  130. body = s.bodyJson
  131. } else {
  132. body = s.bodyString
  133. }
  134. // Get HTTP response
  135. res, err := s.client.PerformRequest(ctx, "POST", path, params, body, http.StatusNotFound)
  136. if err != nil {
  137. return nil, err
  138. }
  139. // TODO(oe): Is 404 really a valid response here?
  140. if res.StatusCode == http.StatusNotFound {
  141. return &FieldCapsResponse{}, nil
  142. }
  143. // Return operation response
  144. ret := new(FieldCapsResponse)
  145. if err := s.client.decoder.Decode(res.Body, ret); err != nil {
  146. return nil, err
  147. }
  148. return ret, nil
  149. }
  150. // -- Request --
  151. // FieldCapsRequest can be used to set up the body to be used in the
  152. // Field Capabilities API.
  153. type FieldCapsRequest struct {
  154. Fields []string `json:"fields"`
  155. }
  156. // -- Response --
  157. // FieldCapsResponse contains field capabilities.
  158. type FieldCapsResponse struct {
  159. Fields map[string]FieldCaps `json:"fields,omitempty"`
  160. }
  161. // FieldCaps contains capabilities of an individual field.
  162. type FieldCaps struct {
  163. Type string `json:"type"`
  164. Searchable bool `json:"searchable"`
  165. Aggregatable bool `json:"aggregatable"`
  166. Indices []string `json:"indices,omitempty"`
  167. NonSearchableIndices []string `json:"non_searchable_indices,omitempty"`
  168. NonAggregatableIndices []string `json:"non_aggregatable_indices,omitempty"`
  169. }