scan_test.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  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. _ "net/http"
  8. "testing"
  9. )
  10. func TestScan(t *testing.T) {
  11. client := setupTestClientAndCreateIndex(t)
  12. tweet1 := tweet{User: "olivere", Message: "Welcome to Golang and Elasticsearch."}
  13. tweet2 := tweet{User: "olivere", Message: "Another unrelated topic."}
  14. tweet3 := tweet{User: "sandrae", Message: "Cycling is fun."}
  15. // Add all documents
  16. _, err := client.Index().Index(testIndexName).Type("tweet").Id("1").BodyJson(&tweet1).Do()
  17. if err != nil {
  18. t.Fatal(err)
  19. }
  20. _, err = client.Index().Index(testIndexName).Type("tweet").Id("2").BodyJson(&tweet2).Do()
  21. if err != nil {
  22. t.Fatal(err)
  23. }
  24. _, err = client.Index().Index(testIndexName).Type("tweet").Id("3").BodyJson(&tweet3).Do()
  25. if err != nil {
  26. t.Fatal(err)
  27. }
  28. _, err = client.Flush().Index(testIndexName).Do()
  29. if err != nil {
  30. t.Fatal(err)
  31. }
  32. // Match all should return all documents
  33. cursor, err := client.Scan(testIndexName).Size(1).Do()
  34. if err != nil {
  35. t.Fatal(err)
  36. }
  37. if cursor.Results == nil {
  38. t.Errorf("expected results != nil; got nil")
  39. }
  40. if cursor.Results.Hits == nil {
  41. t.Errorf("expected results.Hits != nil; got nil")
  42. }
  43. if cursor.Results.Hits.TotalHits != 3 {
  44. t.Errorf("expected results.Hits.TotalHits = %d; got %d", 3, cursor.Results.Hits.TotalHits)
  45. }
  46. if len(cursor.Results.Hits.Hits) != 0 {
  47. t.Errorf("expected len(results.Hits.Hits) = %d; got %d", 0, len(cursor.Results.Hits.Hits))
  48. }
  49. pages := 0
  50. numDocs := 0
  51. for {
  52. searchResult, err := cursor.Next()
  53. if err == EOS {
  54. break
  55. }
  56. if err != nil {
  57. t.Fatal(err)
  58. }
  59. pages += 1
  60. for _, hit := range searchResult.Hits.Hits {
  61. if hit.Index != testIndexName {
  62. t.Errorf("expected SearchResult.Hits.Hit.Index = %q; got %q", testIndexName, hit.Index)
  63. }
  64. item := make(map[string]interface{})
  65. err := json.Unmarshal(*hit.Source, &item)
  66. if err != nil {
  67. t.Fatal(err)
  68. }
  69. numDocs += 1
  70. }
  71. }
  72. if pages <= 0 {
  73. t.Errorf("expected to retrieve at least 1 page; got %d", pages)
  74. }
  75. if numDocs != 3 {
  76. t.Errorf("expected to retrieve %d hits; got %d", 3, numDocs)
  77. }
  78. }
  79. func TestScanWithQuery(t *testing.T) {
  80. client := setupTestClientAndCreateIndex(t)
  81. tweet1 := tweet{User: "olivere", Message: "Welcome to Golang and Elasticsearch."}
  82. tweet2 := tweet{User: "olivere", Message: "Another unrelated topic."}
  83. tweet3 := tweet{User: "sandrae", Message: "Cycling is fun."}
  84. // Add all documents
  85. _, err := client.Index().Index(testIndexName).Type("tweet").Id("1").BodyJson(&tweet1).Do()
  86. if err != nil {
  87. t.Fatal(err)
  88. }
  89. _, err = client.Index().Index(testIndexName).Type("tweet").Id("2").BodyJson(&tweet2).Do()
  90. if err != nil {
  91. t.Fatal(err)
  92. }
  93. _, err = client.Index().Index(testIndexName).Type("tweet").Id("3").BodyJson(&tweet3).Do()
  94. if err != nil {
  95. t.Fatal(err)
  96. }
  97. _, err = client.Flush().Index(testIndexName).Do()
  98. if err != nil {
  99. t.Fatal(err)
  100. }
  101. // Return tweets from olivere only
  102. termQuery := NewTermQuery("user", "olivere")
  103. cursor, err := client.Scan(testIndexName).
  104. Size(1).
  105. Query(termQuery).
  106. Do()
  107. if err != nil {
  108. t.Fatal(err)
  109. }
  110. if cursor.Results == nil {
  111. t.Errorf("expected results != nil; got nil")
  112. }
  113. if cursor.Results.Hits == nil {
  114. t.Errorf("expected results.Hits != nil; got nil")
  115. }
  116. if cursor.Results.Hits.TotalHits != 2 {
  117. t.Errorf("expected results.Hits.TotalHits = %d; got %d", 2, cursor.Results.Hits.TotalHits)
  118. }
  119. if len(cursor.Results.Hits.Hits) != 0 {
  120. t.Errorf("expected len(results.Hits.Hits) = %d; got %d", 0, len(cursor.Results.Hits.Hits))
  121. }
  122. pages := 0
  123. numDocs := 0
  124. for {
  125. searchResult, err := cursor.Next()
  126. if err == EOS {
  127. break
  128. }
  129. if err != nil {
  130. t.Fatal(err)
  131. }
  132. pages += 1
  133. for _, hit := range searchResult.Hits.Hits {
  134. if hit.Index != testIndexName {
  135. t.Errorf("expected SearchResult.Hits.Hit.Index = %q; got %q", testIndexName, hit.Index)
  136. }
  137. item := make(map[string]interface{})
  138. err := json.Unmarshal(*hit.Source, &item)
  139. if err != nil {
  140. t.Fatal(err)
  141. }
  142. numDocs += 1
  143. }
  144. }
  145. if pages <= 0 {
  146. t.Errorf("expected to retrieve at least 1 page; got %d", pages)
  147. }
  148. if numDocs != 2 {
  149. t.Errorf("expected to retrieve %d hits; got %d", 2, numDocs)
  150. }
  151. }
  152. func TestScanAndScrollWithMissingIndex(t *testing.T) {
  153. client := setupTestClient(t) // does not create testIndexName
  154. cursor, err := client.Scan(testIndexName).Scroll("30s").Do()
  155. if err != nil {
  156. t.Fatal(err)
  157. }
  158. if cursor == nil {
  159. t.Fatalf("expected cursor; got: %v", cursor)
  160. }
  161. // First request immediately returns EOS
  162. res, err := cursor.Next()
  163. if err != EOS {
  164. t.Fatal(err)
  165. }
  166. if res != nil {
  167. t.Fatalf("expected results == %v; got: %v", nil, res)
  168. }
  169. }
  170. func TestScanAndScrollWithEmptyIndex(t *testing.T) {
  171. client := setupTestClientAndCreateIndex(t)
  172. if isTravis() {
  173. t.Skip("test on Travis failes regularly with " +
  174. "Error 503 (Service Unavailable): SearchPhaseExecutionException[Failed to execute phase [init_scan], all shards failed]")
  175. }
  176. _, err := client.Flush().Index(testIndexName).WaitIfOngoing(true).Do()
  177. if err != nil {
  178. t.Fatal(err)
  179. }
  180. cursor, err := client.Scan(testIndexName).Scroll("30s").Do()
  181. if err != nil {
  182. t.Fatal(err)
  183. }
  184. if cursor == nil {
  185. t.Fatalf("expected cursor; got: %v", cursor)
  186. }
  187. // First request returns no error, but no hits
  188. res, err := cursor.Next()
  189. if err != nil {
  190. t.Fatal(err)
  191. }
  192. if res == nil {
  193. t.Fatalf("expected results != nil; got: nil")
  194. }
  195. if res.ScrollId == "" {
  196. t.Errorf("expected scrollId in results; got: %q", res.ScrollId)
  197. }
  198. if res.TotalHits() != 0 {
  199. t.Errorf("expected TotalHits() = %d; got %d", 0, res.TotalHits())
  200. }
  201. if res.Hits == nil {
  202. t.Errorf("expected results.Hits != nil; got: nil")
  203. }
  204. if res.Hits.TotalHits != 0 {
  205. t.Errorf("expected results.Hits.TotalHits = %d; got %d", 0, res.Hits.TotalHits)
  206. }
  207. if res.Hits.Hits == nil {
  208. t.Errorf("expected results.Hits.Hits != nil; got: %v", res.Hits.Hits)
  209. }
  210. if len(res.Hits.Hits) != 0 {
  211. t.Errorf("expected len(results.Hits.Hits) == %d; got: %d", 0, len(res.Hits.Hits))
  212. }
  213. // Subsequent requests return EOS
  214. res, err = cursor.Next()
  215. if err != EOS {
  216. t.Fatal(err)
  217. }
  218. if res != nil {
  219. t.Fatalf("expected results == %v; got: %v", nil, res)
  220. }
  221. res, err = cursor.Next()
  222. if err != EOS {
  223. t.Fatal(err)
  224. }
  225. if res != nil {
  226. t.Fatalf("expected results == %v; got: %v", nil, res)
  227. }
  228. }