bulk_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. // Copyright 2012-2015 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. "encoding/json"
  7. "testing"
  8. )
  9. func TestBulk(t *testing.T) {
  10. client := setupTestClientAndCreateIndex(t)
  11. tweet1 := tweet{User: "olivere", Message: "Welcome to Golang and Elasticsearch."}
  12. tweet2 := tweet{User: "sandrae", Message: "Dancing all night long. Yeah."}
  13. index1Req := NewBulkIndexRequest().Index(testIndexName).Type("tweet").Id("1").Doc(tweet1)
  14. index2Req := NewBulkIndexRequest().Index(testIndexName).Type("tweet").Id("2").Doc(tweet2)
  15. delete1Req := NewBulkDeleteRequest().Index(testIndexName).Type("tweet").Id("1")
  16. bulkRequest := client.Bulk()
  17. bulkRequest = bulkRequest.Add(index1Req)
  18. bulkRequest = bulkRequest.Add(index2Req)
  19. bulkRequest = bulkRequest.Add(delete1Req)
  20. if bulkRequest.NumberOfActions() != 3 {
  21. t.Errorf("expected bulkRequest.NumberOfActions %d; got %d", 3, bulkRequest.NumberOfActions())
  22. }
  23. bulkResponse, err := bulkRequest.Do()
  24. if err != nil {
  25. t.Fatal(err)
  26. }
  27. if bulkResponse == nil {
  28. t.Errorf("expected bulkResponse to be != nil; got nil")
  29. }
  30. if bulkRequest.NumberOfActions() != 0 {
  31. t.Errorf("expected bulkRequest.NumberOfActions %d; got %d", 0, bulkRequest.NumberOfActions())
  32. }
  33. // Document with Id="1" should not exist
  34. exists, err := client.Exists().Index(testIndexName).Type("tweet").Id("1").Do()
  35. if err != nil {
  36. t.Fatal(err)
  37. }
  38. if exists {
  39. t.Errorf("expected exists %v; got %v", false, exists)
  40. }
  41. // Document with Id="2" should exist
  42. exists, err = client.Exists().Index(testIndexName).Type("tweet").Id("2").Do()
  43. if err != nil {
  44. t.Fatal(err)
  45. }
  46. if !exists {
  47. t.Errorf("expected exists %v; got %v", true, exists)
  48. }
  49. // Update
  50. updateDoc := struct {
  51. Retweets int `json:"retweets"`
  52. }{
  53. 42,
  54. }
  55. update1Req := NewBulkUpdateRequest().Index(testIndexName).Type("tweet").Id("2").Doc(&updateDoc)
  56. bulkRequest = client.Bulk()
  57. bulkRequest = bulkRequest.Add(update1Req)
  58. if bulkRequest.NumberOfActions() != 1 {
  59. t.Errorf("expected bulkRequest.NumberOfActions %d; got %d", 1, bulkRequest.NumberOfActions())
  60. }
  61. bulkResponse, err = bulkRequest.Do()
  62. if err != nil {
  63. t.Fatal(err)
  64. }
  65. if bulkResponse == nil {
  66. t.Errorf("expected bulkResponse to be != nil; got nil")
  67. }
  68. if bulkRequest.NumberOfActions() != 0 {
  69. t.Errorf("expected bulkRequest.NumberOfActions %d; got %d", 0, bulkRequest.NumberOfActions())
  70. }
  71. // Document with Id="1" should have a retweets count of 42
  72. doc, err := client.Get().Index(testIndexName).Type("tweet").Id("2").Do()
  73. if err != nil {
  74. t.Fatal(err)
  75. }
  76. if doc == nil {
  77. t.Fatal("expected doc to be != nil; got nil")
  78. }
  79. if !doc.Found {
  80. t.Fatalf("expected doc to be found; got found = %v", doc.Found)
  81. }
  82. if doc.Source == nil {
  83. t.Fatal("expected doc source to be != nil; got nil")
  84. }
  85. var updatedTweet tweet
  86. err = json.Unmarshal(*doc.Source, &updatedTweet)
  87. if err != nil {
  88. t.Fatal(err)
  89. }
  90. if updatedTweet.Retweets != 42 {
  91. t.Errorf("expected updated tweet retweets = %v; got %v", 42, updatedTweet.Retweets)
  92. }
  93. }
  94. func TestBulkWithIndexSetOnClient(t *testing.T) {
  95. client := setupTestClientAndCreateIndex(t)
  96. tweet1 := tweet{User: "olivere", Message: "Welcome to Golang and Elasticsearch."}
  97. tweet2 := tweet{User: "sandrae", Message: "Dancing all night long. Yeah."}
  98. index1Req := NewBulkIndexRequest().Index(testIndexName).Type("tweet").Id("1").Doc(tweet1)
  99. index2Req := NewBulkIndexRequest().Index(testIndexName).Type("tweet").Id("2").Doc(tweet2)
  100. delete1Req := NewBulkDeleteRequest().Index(testIndexName).Type("tweet").Id("1")
  101. bulkRequest := client.Bulk().Index(testIndexName).Type("tweet")
  102. bulkRequest = bulkRequest.Add(index1Req)
  103. bulkRequest = bulkRequest.Add(index2Req)
  104. bulkRequest = bulkRequest.Add(delete1Req)
  105. if bulkRequest.NumberOfActions() != 3 {
  106. t.Errorf("expected bulkRequest.NumberOfActions %d; got %d", 3, bulkRequest.NumberOfActions())
  107. }
  108. bulkResponse, err := bulkRequest.Do()
  109. if err != nil {
  110. t.Fatal(err)
  111. }
  112. if bulkResponse == nil {
  113. t.Errorf("expected bulkResponse to be != nil; got nil")
  114. }
  115. // Document with Id="1" should not exist
  116. exists, err := client.Exists().Index(testIndexName).Type("tweet").Id("1").Do()
  117. if err != nil {
  118. t.Fatal(err)
  119. }
  120. if exists {
  121. t.Errorf("expected exists %v; got %v", false, exists)
  122. }
  123. // Document with Id="2" should exist
  124. exists, err = client.Exists().Index(testIndexName).Type("tweet").Id("2").Do()
  125. if err != nil {
  126. t.Fatal(err)
  127. }
  128. if !exists {
  129. t.Errorf("expected exists %v; got %v", true, exists)
  130. }
  131. }
  132. func TestBulkRequestsSerialization(t *testing.T) {
  133. client := setupTestClientAndCreateIndex(t)
  134. tweet1 := tweet{User: "olivere", Message: "Welcome to Golang and Elasticsearch."}
  135. tweet2 := tweet{User: "sandrae", Message: "Dancing all night long. Yeah."}
  136. index1Req := NewBulkIndexRequest().Index(testIndexName).Type("tweet").Id("1").Doc(tweet1)
  137. index2Req := NewBulkIndexRequest().OpType("create").Index(testIndexName).Type("tweet").Id("2").Doc(tweet2)
  138. delete1Req := NewBulkDeleteRequest().Index(testIndexName).Type("tweet").Id("1")
  139. update2Req := NewBulkUpdateRequest().Index(testIndexName).Type("tweet").Id("2").
  140. Doc(struct {
  141. Retweets int `json:"retweets"`
  142. }{
  143. Retweets: 42,
  144. })
  145. bulkRequest := client.Bulk()
  146. bulkRequest = bulkRequest.Add(index1Req)
  147. bulkRequest = bulkRequest.Add(index2Req)
  148. bulkRequest = bulkRequest.Add(delete1Req)
  149. bulkRequest = bulkRequest.Add(update2Req)
  150. if bulkRequest.NumberOfActions() != 4 {
  151. t.Errorf("expected bulkRequest.NumberOfActions %d; got %d", 4, bulkRequest.NumberOfActions())
  152. }
  153. expected := `{"index":{"_id":"1","_index":"` + testIndexName + `","_type":"tweet"}}
  154. {"user":"olivere","message":"Welcome to Golang and Elasticsearch.","retweets":0,"created":"0001-01-01T00:00:00Z"}
  155. {"create":{"_id":"2","_index":"` + testIndexName + `","_type":"tweet"}}
  156. {"user":"sandrae","message":"Dancing all night long. Yeah.","retweets":0,"created":"0001-01-01T00:00:00Z"}
  157. {"delete":{"_id":"1","_index":"` + testIndexName + `","_type":"tweet"}}
  158. {"update":{"_id":"2","_index":"` + testIndexName + `","_type":"tweet"}}
  159. {"doc":{"retweets":42}}
  160. `
  161. got, err := bulkRequest.bodyAsString()
  162. if err != nil {
  163. t.Fatalf("expected no error, got: %v", err)
  164. }
  165. if got != expected {
  166. t.Errorf("expected\n%s\ngot:\n%s", expected, got)
  167. }
  168. // Run the bulk request
  169. bulkResponse, err := bulkRequest.Do()
  170. if err != nil {
  171. t.Fatal(err)
  172. }
  173. if bulkResponse == nil {
  174. t.Errorf("expected bulkResponse to be != nil; got nil")
  175. }
  176. if bulkResponse.Took == 0 {
  177. t.Errorf("expected took to be > 0; got %d", bulkResponse.Took)
  178. }
  179. if bulkResponse.Errors {
  180. t.Errorf("expected errors to be %v; got %v", false, bulkResponse.Errors)
  181. }
  182. if len(bulkResponse.Items) != 4 {
  183. t.Fatalf("expected 4 result items; got %d", len(bulkResponse.Items))
  184. }
  185. // Indexed actions
  186. indexed := bulkResponse.Indexed()
  187. if indexed == nil {
  188. t.Fatal("expected indexed to be != nil; got nil")
  189. }
  190. if len(indexed) != 1 {
  191. t.Fatalf("expected len(indexed) == %d; got %d", 1, len(indexed))
  192. }
  193. if indexed[0].Id != "1" {
  194. t.Errorf("expected indexed[0].Id == %s; got %s", "1", indexed[0].Id)
  195. }
  196. if indexed[0].Status != 201 {
  197. t.Errorf("expected indexed[0].Status == %d; got %d", 201, indexed[0].Status)
  198. }
  199. // Created actions
  200. created := bulkResponse.Created()
  201. if created == nil {
  202. t.Fatal("expected created to be != nil; got nil")
  203. }
  204. if len(created) != 1 {
  205. t.Fatalf("expected len(created) == %d; got %d", 1, len(created))
  206. }
  207. if created[0].Id != "2" {
  208. t.Errorf("expected created[0].Id == %s; got %s", "2", created[0].Id)
  209. }
  210. if created[0].Status != 201 {
  211. t.Errorf("expected created[0].Status == %d; got %d", 201, created[0].Status)
  212. }
  213. // Deleted actions
  214. deleted := bulkResponse.Deleted()
  215. if deleted == nil {
  216. t.Fatal("expected deleted to be != nil; got nil")
  217. }
  218. if len(deleted) != 1 {
  219. t.Fatalf("expected len(deleted) == %d; got %d", 1, len(deleted))
  220. }
  221. if deleted[0].Id != "1" {
  222. t.Errorf("expected deleted[0].Id == %s; got %s", "1", deleted[0].Id)
  223. }
  224. if deleted[0].Status != 200 {
  225. t.Errorf("expected deleted[0].Status == %d; got %d", 200, deleted[0].Status)
  226. }
  227. if !deleted[0].Found {
  228. t.Errorf("expected deleted[0].Found == %v; got %v", true, deleted[0].Found)
  229. }
  230. // Updated actions
  231. updated := bulkResponse.Updated()
  232. if updated == nil {
  233. t.Fatal("expected updated to be != nil; got nil")
  234. }
  235. if len(updated) != 1 {
  236. t.Fatalf("expected len(updated) == %d; got %d", 1, len(updated))
  237. }
  238. if updated[0].Id != "2" {
  239. t.Errorf("expected updated[0].Id == %s; got %s", "2", updated[0].Id)
  240. }
  241. if updated[0].Status != 200 {
  242. t.Errorf("expected updated[0].Status == %d; got %d", 200, updated[0].Status)
  243. }
  244. if updated[0].Version != 2 {
  245. t.Errorf("expected updated[0].Version == %d; got %d", 2, updated[0].Version)
  246. }
  247. // Succeeded actions
  248. succeeded := bulkResponse.Succeeded()
  249. if succeeded == nil {
  250. t.Fatal("expected succeeded to be != nil; got nil")
  251. }
  252. if len(succeeded) != 4 {
  253. t.Fatalf("expected len(succeeded) == %d; got %d", 4, len(succeeded))
  254. }
  255. // ById
  256. id1Results := bulkResponse.ById("1")
  257. if id1Results == nil {
  258. t.Fatal("expected id1Results to be != nil; got nil")
  259. }
  260. if len(id1Results) != 2 {
  261. t.Fatalf("expected len(id1Results) == %d; got %d", 2, len(id1Results))
  262. }
  263. if id1Results[0].Id != "1" {
  264. t.Errorf("expected id1Results[0].Id == %s; got %s", "1", id1Results[0].Id)
  265. }
  266. if id1Results[0].Status != 201 {
  267. t.Errorf("expected id1Results[0].Status == %d; got %d", 201, id1Results[0].Status)
  268. }
  269. if id1Results[0].Version != 1 {
  270. t.Errorf("expected id1Results[0].Version == %d; got %d", 1, id1Results[0].Version)
  271. }
  272. if id1Results[1].Id != "1" {
  273. t.Errorf("expected id1Results[1].Id == %s; got %s", "1", id1Results[1].Id)
  274. }
  275. if id1Results[1].Status != 200 {
  276. t.Errorf("expected id1Results[1].Status == %d; got %d", 200, id1Results[1].Status)
  277. }
  278. if id1Results[1].Version != 2 {
  279. t.Errorf("expected id1Results[1].Version == %d; got %d", 2, id1Results[1].Version)
  280. }
  281. }
  282. func TestFailedBulkRequests(t *testing.T) {
  283. js := `{
  284. "took" : 2,
  285. "errors" : true,
  286. "items" : [ {
  287. "index" : {
  288. "_index" : "elastic-test",
  289. "_type" : "tweet",
  290. "_id" : "1",
  291. "_version" : 1,
  292. "status" : 201
  293. }
  294. }, {
  295. "create" : {
  296. "_index" : "elastic-test",
  297. "_type" : "tweet",
  298. "_id" : "2",
  299. "_version" : 1,
  300. "status" : 423,
  301. "error" : "Locked"
  302. }
  303. }, {
  304. "delete" : {
  305. "_index" : "elastic-test",
  306. "_type" : "tweet",
  307. "_id" : "1",
  308. "_version" : 2,
  309. "status" : 404,
  310. "found" : false
  311. }
  312. }, {
  313. "update" : {
  314. "_index" : "elastic-test",
  315. "_type" : "tweet",
  316. "_id" : "2",
  317. "_version" : 2,
  318. "status" : 200
  319. }
  320. } ]
  321. }`
  322. var resp BulkResponse
  323. err := json.Unmarshal([]byte(js), &resp)
  324. if err != nil {
  325. t.Fatal(err)
  326. }
  327. failed := resp.Failed()
  328. if len(failed) != 2 {
  329. t.Errorf("expected %d failed items; got: %d", 2, len(failed))
  330. }
  331. }