delete.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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/url"
  9. "net/http"
  10. "gopkg.in/olivere/elastic.v5/uritemplates"
  11. )
  12. // DeleteService allows to delete a typed JSON document from a specified
  13. // index based on its id.
  14. //
  15. // See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/docs-delete.html
  16. // for details.
  17. type DeleteService struct {
  18. client *Client
  19. pretty bool
  20. id string
  21. index string
  22. typ string
  23. routing string
  24. timeout string
  25. version interface{}
  26. versionType string
  27. waitForActiveShards string
  28. parent string
  29. refresh string
  30. }
  31. // NewDeleteService creates a new DeleteService.
  32. func NewDeleteService(client *Client) *DeleteService {
  33. return &DeleteService{
  34. client: client,
  35. }
  36. }
  37. // Type is the type of the document.
  38. func (s *DeleteService) Type(typ string) *DeleteService {
  39. s.typ = typ
  40. return s
  41. }
  42. // Id is the document ID.
  43. func (s *DeleteService) Id(id string) *DeleteService {
  44. s.id = id
  45. return s
  46. }
  47. // Index is the name of the index.
  48. func (s *DeleteService) Index(index string) *DeleteService {
  49. s.index = index
  50. return s
  51. }
  52. // Routing is a specific routing value.
  53. func (s *DeleteService) Routing(routing string) *DeleteService {
  54. s.routing = routing
  55. return s
  56. }
  57. // Timeout is an explicit operation timeout.
  58. func (s *DeleteService) Timeout(timeout string) *DeleteService {
  59. s.timeout = timeout
  60. return s
  61. }
  62. // Version is an explicit version number for concurrency control.
  63. func (s *DeleteService) Version(version interface{}) *DeleteService {
  64. s.version = version
  65. return s
  66. }
  67. // VersionType is a specific version type.
  68. func (s *DeleteService) VersionType(versionType string) *DeleteService {
  69. s.versionType = versionType
  70. return s
  71. }
  72. // WaitForActiveShards sets the number of shard copies that must be active
  73. // before proceeding with the delete operation. Defaults to 1, meaning the
  74. // primary shard only. Set to `all` for all shard copies, otherwise set to
  75. // any non-negative value less than or equal to the total number of copies
  76. // for the shard (number of replicas + 1).
  77. func (s *DeleteService) WaitForActiveShards(waitForActiveShards string) *DeleteService {
  78. s.waitForActiveShards = waitForActiveShards
  79. return s
  80. }
  81. // Parent is the ID of parent document.
  82. func (s *DeleteService) Parent(parent string) *DeleteService {
  83. s.parent = parent
  84. return s
  85. }
  86. // Refresh the index after performing the operation.
  87. func (s *DeleteService) Refresh(refresh string) *DeleteService {
  88. s.refresh = refresh
  89. return s
  90. }
  91. // Pretty indicates that the JSON response be indented and human readable.
  92. func (s *DeleteService) Pretty(pretty bool) *DeleteService {
  93. s.pretty = pretty
  94. return s
  95. }
  96. // buildURL builds the URL for the operation.
  97. func (s *DeleteService) buildURL() (string, url.Values, error) {
  98. // Build URL
  99. path, err := uritemplates.Expand("/{index}/{type}/{id}", map[string]string{
  100. "index": s.index,
  101. "type": s.typ,
  102. "id": s.id,
  103. })
  104. if err != nil {
  105. return "", url.Values{}, err
  106. }
  107. // Add query string parameters
  108. params := url.Values{}
  109. if s.pretty {
  110. params.Set("pretty", "1")
  111. }
  112. if s.refresh != "" {
  113. params.Set("refresh", s.refresh)
  114. }
  115. if s.routing != "" {
  116. params.Set("routing", s.routing)
  117. }
  118. if s.timeout != "" {
  119. params.Set("timeout", s.timeout)
  120. }
  121. if s.version != nil {
  122. params.Set("version", fmt.Sprintf("%v", s.version))
  123. }
  124. if s.versionType != "" {
  125. params.Set("version_type", s.versionType)
  126. }
  127. if s.waitForActiveShards != "" {
  128. params.Set("wait_for_active_shards", s.waitForActiveShards)
  129. }
  130. if s.parent != "" {
  131. params.Set("parent", s.parent)
  132. }
  133. return path, params, nil
  134. }
  135. // Validate checks if the operation is valid.
  136. func (s *DeleteService) Validate() error {
  137. var invalid []string
  138. if s.typ == "" {
  139. invalid = append(invalid, "Type")
  140. }
  141. if s.id == "" {
  142. invalid = append(invalid, "Id")
  143. }
  144. if s.index == "" {
  145. invalid = append(invalid, "Index")
  146. }
  147. if len(invalid) > 0 {
  148. return fmt.Errorf("missing required fields: %v", invalid)
  149. }
  150. return nil
  151. }
  152. // Do executes the operation. If the document is not found (404), Elasticsearch will
  153. // still return a response. This response is serialized and returned as well. In other
  154. // words, for HTTP status code 404, both an error and a response might be returned.
  155. func (s *DeleteService) Do(ctx context.Context) (*DeleteResponse, error) {
  156. // Check pre-conditions
  157. if err := s.Validate(); err != nil {
  158. return nil, err
  159. }
  160. // Get URL for request
  161. path, params, err := s.buildURL()
  162. if err != nil {
  163. return nil, err
  164. }
  165. // Get HTTP response
  166. res, err := s.client.PerformRequest(ctx, "DELETE", path, params, nil, http.StatusNotFound)
  167. if err != nil {
  168. return nil, err
  169. }
  170. // Return operation response
  171. ret := new(DeleteResponse)
  172. if err := s.client.decoder.Decode(res.Body, ret); err != nil {
  173. return nil, err
  174. }
  175. // If we have a 404, we return both a result and an error, just like ES does
  176. if res.StatusCode == http.StatusNotFound {
  177. return ret, &Error{Status: http.StatusNotFound}
  178. }
  179. return ret, nil
  180. }
  181. // -- Result of a delete request.
  182. // DeleteResponse is the outcome of running DeleteService.Do.
  183. type DeleteResponse struct {
  184. Index string `json:"_index,omitempty"`
  185. Type string `json:"_type,omitempty"`
  186. Id string `json:"_id,omitempty"`
  187. Version int64 `json:"_version,omitempty"`
  188. Result string `json:"result,omitempty"`
  189. Shards *ShardsInfo `json:"_shards,omitempty"`
  190. SeqNo int64 `json:"_seq_no,omitempty"`
  191. PrimaryTerm int64 `json:"_primary_term,omitempty"`
  192. Status int `json:"status,omitempty"`
  193. ForcedRefresh bool `json:"forced_refresh,omitempty"`
  194. Found bool `json:"found,omitempty"`
  195. }